Codifica dei caratteri in .NETCharacter Encoding in .NET

I caratteri sono entità astratte rappresentabili in molti modi.Characters are abstract entities that can be represented in many different ways. La codifica dei caratteri è un sistema che abbina ogni carattere di un set di caratteri supportato a un valore che lo rappresenta.A character encoding is a system that pairs each character in a supported character set with some value that represents that character. Il codice Morse, ad esempio, è una codifica dei caratteri che abbina ogni carattere dell'alfabeto romano a una serie di punti e linee utilizzabili per la trasmissione su linee telegrafiche.For example, Morse code is a character encoding that pairs each character in the Roman alphabet with a pattern of dots and dashes that are suitable for transmission over telegraph lines. La codifica dei caratteri per i computer abbina ogni carattere di un set di caratteri supportato a un valore numerico che lo rappresenta.A character encoding for computers pairs each character in a supported character set with a numeric value that represents that character. La codifica dei caratteri presenta due componenti distinti:A character encoding has two distinct components:

  • Un codificatore, che converte una sequenza di caratteri in una sequenza di valori numerici (byte).An encoder, which translates a sequence of characters into a sequence of numeric values (bytes).

  • Un decodificatore, che converte una sequenza di byte in una sequenza di caratteri.A decoder, which translates a sequence of bytes into a sequence of characters.

La codifica dei caratteri descrive le regole in base alle quali operano un codificatore e un decodificatore.Character encoding describes the rules by which an encoder and a decoder operate. Ad esempio, la classe UTF8Encoding descrive le regole per la codifica e la decodifica con Unicode Transformation Format a 8 bit (UTF-8), che usa da uno a quattro byte per rappresentare un singolo carattere Unicode.For example, the UTF8Encoding class describes the rules for encoding to, and decoding from, 8-bit Unicode Transformation Format (UTF-8), which uses one to four bytes to represent a single Unicode character. La codifica e la decodifica possono includere anche la convalida.Encoding and decoding can also include validation. Ad esempio, la classe UnicodeEncoding controlla tutti i surrogati per assicurarsi che costituiscano coppie di surrogati valide.For example, the UnicodeEncoding class checks all surrogates to make sure they constitute valid surrogate pairs. Una coppia di surrogati è costituita da un carattere con un punto di codice compreso tra U+D800 e U+DBFF seguito da un carattere con un punto di codice compreso tra U+DC00 e U+DFFF. Una strategia di fallback determina come un codificatore gestisce i caratteri non validi o come un decodificatore gestisce i byte non validi.(A surrogate pair consists of a character with a code point that ranges from U+D800 to U+DBFF followed by a character with a code point that ranges from U+DC00 to U+DFFF.) A fallback strategy determines how an encoder handles invalid characters or how a decoder handles invalid bytes.

Avviso

Le classi di codifica in .NET consentono di archiviare e convertire i dati di tipo carattere..NET encoding classes provide a way to store and convert character data. Non devono essere usate per archiviare i dati binari in formato stringa.They should not be used to store binary data in string form. In base alla codifica usata, la conversione dei dati binari in formato stringa con le classi Encoding può introdurre un comportamento imprevisto e generare dati non accurati o danneggiati.Depending on the encoding used, converting binary data to string format with the encoding classes can introduce unexpected behavior and produce inaccurate or corrupted data. Per convertire i dati binari in un formato stringa, usare il metodo Convert.ToBase64String .To convert binary data to a string form, use the Convert.ToBase64String method.

.NET usa la codifica UTF-16 (rappresentata dalla classe UnicodeEncoding) per rappresentare i caratteri e le stringhe..NET uses the UTF-16 encoding (represented by the UnicodeEncoding class) to represent characters and strings. Le applicazioni destinate a Common Language Runtime usano codificatori per eseguire il mapping di rappresentazioni di caratteri Unicode supportate da Common Language Runtime ad altri schemi di codifica.Applications that target the common language runtime use encoders to map Unicode character representations supported by the common language runtime to other encoding schemes. Usano i decodificatori per eseguire il mapping di caratteri da codifiche non Unicode a Unicode.They use decoders to map characters from non-Unicode encodings to Unicode.

Questo argomento include le sezioni seguenti:This topic consists of the following sections:

Codifiche in .NETEncodings in .NET

Tutte le classi Encoding dei caratteri in .NET ereditano dalla classe System.Text.Encoding, una classe astratta che definisce la funzionalità comune a tutte le codifiche dei caratteri.All character encoding classes in .NET inherit from the System.Text.Encoding class, which is an abstract class that defines the functionality common to all character encodings. Per accedere ai singoli oggetti di codifica implementati in .NET, eseguire le operazioni seguenti:To access the individual encoding objects implemented in .NET, do the following:

  • Usare le proprietà statiche della classe Encoding, che restituiscono oggetti che rappresentano le codifiche dei caratteri standard disponibili in .NET (ASCII, UTF-7, UTF-8, UTF-16 e UTF-32).Use the static properties of the Encoding class, which return objects that represent the standard character encodings available in .NET (ASCII, UTF-7, UTF-8, UTF-16, and UTF-32). Ad esempio, la proprietà Encoding.Unicode restituisce un oggetto UnicodeEncoding .For example, the Encoding.Unicode property returns a UnicodeEncoding object. Ogni oggetto usa il fallback di sostituzione per gestire le stringhe che non può codificare e i byte che non può decodificare.Each object uses replacement fallback to handle strings that it cannot encode and bytes that it cannot decode. Per altre informazioni, vedere la sezione Replacement Fallback .(For more information, see the Replacement Fallback section.)

  • Chiamare il costruttore di classe della codifica.Call the encoding's class constructor. In questo modo è possibile creare istanze di oggetti per le codifiche ASCII, UTF-7, UTF-8, UTF-16 e UTF-32.Objects for the ASCII, UTF-7, UTF-8, UTF-16, and UTF-32 encodings can be instantiated in this way. Per impostazione predefinita, ogni oggetto usa il fallback di sostituzione per gestire le stringhe che non può codificare e i byte che non può decodificare, ma è possibile specificare che invece deve essere generata un'eccezione.By default, each object uses replacement fallback to handle strings that it cannot encode and bytes that it cannot decode, but you can specify that an exception should be thrown instead. Per altre informazioni, vedere le sezioni Replacement Fallback e Exception Fallback .(For more information, see the Replacement Fallback and Exception Fallback sections.)

  • Chiamare il costruttore Encoding.Encoding(Int32) e passargli un Integer che rappresenta la codifica.Call the Encoding.Encoding(Int32) constructor and pass it an integer that represents the encoding. Gli oggetti di codifica standard usano il fallback di sostituzione e gli oggetti di codifica della tabella codici e Double Byte Character Set (DBCS) usano il fallback con mapping più appropriato per gestire le stringhe che non possono codificare e i byte che non possono decodificare.Standard encoding objects use replacement fallback, and code page and double-byte character set (DBCS) encoding objects use best-fit fallback to handle strings that they cannot encode and bytes that they cannot decode. Per altre informazioni, vedere la sezione Best-Fit Fallback .(For more information, see the Best-Fit Fallback section.)

  • Chiamare il metodo Encoding.GetEncoding, che restituisce qualsiasi codifica standard, della tabella codici o DBCS disponibile in .NET.Call the Encoding.GetEncoding method, which returns any standard, code page, or DBCS encoding available in .NET. Gli overload consentono di specificare un oggetto di fallback sia per il codificatore che per il decodificatore.Overloads let you specify a fallback object for both the encoder and the decoder.

Nota

Lo standard Unicode assegna un punto di codice (un numero) e un nome a ciascun carattere in ogni script supportato.The Unicode Standard assigns a code point (a number) and a name to each character in every supported script. Ad esempio, il carattere "A" è rappresentato dal punto di codice U+0041 e dal nome "LATIN CAPITAL LETTER A".For example, the character "A" is represented by the code point U+0041 and the name "LATIN CAPITAL LETTER A". Le codifiche Unicode Transformation Format (UTF) definiscono i modi per codificare quel punto di codice in una sequenza di uno o più byte.The Unicode Transformation Format (UTF) encodings define ways to encode that code point into a sequence of one or more bytes. Uno schema di codifica Unicode semplifica lo sviluppo di applicazioni internazionali, perché consente di rappresentare in una sola codifica i caratteri di qualsiasi set di caratteri.A Unicode encoding scheme simplifies world-ready application development because it allows characters from any character set to be represented in a single encoding. Gli sviluppatori di applicazioni non devono più tenere traccia dello schema di codifica usato per produrre i caratteri per una lingua o un sistema di scrittura specifico e i dati possono essere condivisi tra i sistemi a livello internazionale senza essere danneggiati.Application developers no longer have to keep track of the encoding scheme that was used to produce characters for a specific language or writing system, and data can be shared among systems internationally without being corrupted.

.NET supporta tre codifiche definite dallo standard Unicode: UTF-8, UTF-16 e UTF-32..NET supports three encodings defined by the Unicode standard: UTF-8, UTF-16, and UTF-32. Per altre informazioni, vedere lo standard Unicode nella home page di Unicode.For more information, see The Unicode Standard at the Unicode home page.

È possibile recuperare informazioni su tutte le codifiche disponibili in .NET chiamando il metodo Encoding.GetEncodings.You can retrieve information about all the encodings available in .NET by calling the Encoding.GetEncodings method. .NET supporta i sistemi di codifica dei caratteri elencati nella tabella seguente..NET supports the character encoding systems listed in the following table.

CodificaEncoding ClasseClass DescriptionDescription Vantaggi/SvantaggiAdvantages/disadvantages
nonASCII ASCIIEncoding Codifica un intervallo limitato di caratteri usando i sette bit più bassi di un byte.Encodes a limited range of characters by using the lower seven bits of a byte. Poiché questa codifica supporta solo i valori dei caratteri compresi tra U+0000 e U+007F, nella maggior parte dei casi non è adatta per le applicazioni internazionalizzate.Because this encoding only supports character values from U+0000 through U+007F, in most cases it is inadequate for internationalized applications.
UTF-7UTF-7 UTF7Encoding Rappresenta i caratteri come sequenze di caratteri ASCII a 7 bit.Represents characters as sequences of 7-bit ASCII characters. I caratteri Unicode non ASCII sono rappresentati da una sequenza di escape di caratteri ASCII.Non-ASCII Unicode characters are represented by an escape sequence of ASCII characters. UTF-7 supporta protocolli di newsgroup e di posta elettronica.UTF-7 supports protocols such as email and newsgroup protocols. UTF-7 non è tuttavia particolarmente sicura o affidabile.However, UTF-7 is not particularly secure or robust. In alcuni casi, la modifica di un bit può alterare radicalmente l'interpretazione di un'intera stringa UTF-7.In some cases, changing one bit can radically alter the interpretation of an entire UTF-7 string. In altri casi, stringhe UTF-7 diverse possono codificare lo stesso testo.In other cases, different UTF-7 strings can encode the same text. Per le sequenze che includono caratteri non ASCII, UTF-7 richiede più spazio di UTF-8 e la codifica/decodifica è più lenta.For sequences that include non-ASCII characters, UTF-7 requires more space than UTF-8, and encoding/decoding is slower. Di conseguenza, è consigliabile usare UTF-8 anziché UTF-7, se possibile.Consequently, you should use UTF-8 instead of UTF-7 if possible.
UTF-8UTF-8 UTF8Encoding Rappresenta ogni punto di codice Unicode come sequenza che include da uno a quattro byte.Represents each Unicode code point as a sequence of one to four bytes. UTF-8 supporta dimensioni dati a 8 bit e funziona bene con molti sistemi operativi esistenti.UTF-8 supports 8-bit data sizes and works well with many existing operating systems. Per l'intervallo di caratteri ASCII, UTF-8 è identica alla codifica ASCII e consente un più ampio set di caratteri.For the ASCII range of characters, UTF-8 is identical to ASCII encoding and allows a broader set of characters. Tuttavia, per gli script in cinese-giapponese-coreano (CJK), UTF-8 può richiedere tre byte per ogni carattere e potrebbe generare dimensioni dati maggiori di UTF-16.However, for Chinese-Japanese-Korean (CJK) scripts, UTF-8 can require three bytes for each character, and can potentially cause larger data sizes than UTF-16. Si noti che a volte la quantità di dati ASCII, ad esempio di tag HTML, giustifica l'aumento delle dimensioni per la gamma CJK.Note that sometimes the amount of ASCII data, such as HTML tags, justifies the increased size for the CJK range.
UTF-16UTF-16 UnicodeEncoding Rappresenta ogni punto di codice Unicode come sequenza di uno o due Integer a 16 bit.Represents each Unicode code point as a sequence of one or two 16-bit integers. I caratteri Unicode più comuni richiedono un solo punto di codice UTF-16, anche se i caratteri supplementari Unicode (U+10000 e successivi) richiedono due punti di codice surrogati UTF-16.Most common Unicode characters require only one UTF-16 code point, although Unicode supplementary characters (U+10000 and greater) require two UTF-16 surrogate code points. Sono supportati sia ordini dei byte little-endian che big-endian.Both little-endian and big-endian byte orders are supported. La codifica UTF-16 viene usata da Common Language Runtime per rappresentare i valori Char e String e dal sistema operativo Windows per rappresentare i valori WCHAR .UTF-16 encoding is used by the common language runtime to represent Char and String values, and it is used by the Windows operating system to represent WCHAR values.
UTF-32UTF-32 UTF32Encoding Rappresenta ogni punto di codice Unicode come Integer a 32 bit.Represents each Unicode code point as a 32-bit integer. Sono supportati sia ordini dei byte little-endian che big-endian.Both little-endian and big-endian byte orders are supported. La codifica UTF-32 viene usata quando le applicazioni vogliono evitare il comportamento dei punti di codice surrogati della codifica UTF-16 in sistemi operativi per cui lo spazio codificato è estremamente importante.UTF-32 encoding is used when applications want to avoid the surrogate code point behavior of UTF-16 encoding on operating systems for which encoded space is too important. I singoli glifi visualizzati su uno schermo possono comunque essere codificati con più di un carattere UTF-32.Single glyphs rendered on a display can still be encoded with more than one UTF-32 character.
Codifiche ANSI/ISOANSI/ISO encodings Forniscono il supporto per un'ampia gamma di tabelle codici.Provides support for a variety of code pages. Nei sistemi operativi Windows, le tabelle codici vengono usate per supportare una lingua specifica o un gruppo di lingue.On Windows operating systems, code pages are used to support a specific language or group of languages. Per una tabella che elenca le tabelle codici supportate da .NET, vedere la classe Encoding.For a table that lists the code pages supported by .NET, see the Encoding class. È possibile recuperare un oggetto di codifica per una particolare tabella codici chiamando il metodo Encoding.GetEncoding(Int32) .You can retrieve an encoding object for a particular code page by calling the Encoding.GetEncoding(Int32) method. Una tabella codici contiene 256 punti di codice ed è in base zero.A code page contains 256 code points and is zero-based. Nella maggior parte delle tabelle codici, i punti di codice da 0 a 127 rappresentano il set di caratteri ASCII e i punti di codice da 128 a 255 sono molto diversi da una tabella codici all'altra.In most code pages, code points 0 through 127 represent the ASCII character set, and code points 128 through 255 differ significantly between code pages. Ad esempio, la tabella codici 1252 fornisce i caratteri per i sistemi di scrittura in caratteri latini, tra cui inglese, tedesco e francese.For example, code page 1252 provides the characters for Latin writing systems, including English, German, and French. Gli ultimi 128 punti di codice nella tabella codici 1252 contengono i caratteri accentati.The last 128 code points in code page 1252 contain the accent characters. La tabella codici 1253 fornisce i codici carattere necessari nel sistema di scrittura in caratteri greci.Code page 1253 provides character codes that are required in the Greek writing system. Gli ultimi 128 punti di codice nella tabella codici 1253 contengono i caratteri greci.The last 128 code points in code page 1253 contain the Greek characters. Di conseguenza, un'applicazione che si basa su tabelle codici ANSI non può archiviare il greco e il tedesco nello stesso flusso di testo, a meno che non includa un identificatore indicante la tabella codici a cui si fa riferimento.As a result, an application that relies on ANSI code pages cannot store Greek and German in the same text stream unless it includes an identifier that indicates the referenced code page.
Codifiche Double Byte Character Set (DBCS)Double-byte character set (DBCS) encodings Supportano lingue, quali cinese, giapponese e coreano, che contengono più di 256 caratteri.Supports languages, such as Chinese, Japanese, and Korean, that contain more than 256 characters. In un set DBCS, una coppia di punti di codice (un byte doppio) rappresenta ogni carattere.In a DBCS, a pair of code points (a double byte) represents each character. La proprietà Encoding.IsSingleByte restituisce false per le codifiche DBCS.The Encoding.IsSingleByte property returns false for DBCS encodings. È possibile recuperare un oggetto di codifica per un particolare DBCS chiamando il metodo Encoding.GetEncoding(Int32) .You can retrieve an encoding object for a particular DBCS by calling the Encoding.GetEncoding(Int32) method. In un set DBCS, una coppia di punti di codice (un byte doppio) rappresenta ogni carattere.In a DBCS, a pair of code points (a double byte) represents each character. Quando un'applicazione gestisce dati DBCS, il primo byte di un carattere DBCS (il byte di apertura) viene elaborato in combinazione con il byte di chiusura che lo segue immediatamente.When an application handles DBCS data, the first byte of a DBCS character (the lead byte) is processed in combination with the trail byte that immediately follows it. Poiché una singola coppia di punti di codice a doppio byte può rappresentare caratteri diversi a seconda della tabella codici, questo schema non consente la combinazione di due lingue, quali giapponese e cinese, nello stesso flusso di dati.Because a single pair of double-byte code points can represent different characters depending on the code page, this scheme still does not allow for the combination of two languages, such as Japanese and Chinese, in the same data stream.

Queste codifiche consentono di lavorare con i caratteri Unicode e con le codifiche più comunemente usate nelle applicazioni legacy.These encodings enable you to work with Unicode characters as well as with encodings that are most commonly used in legacy applications. Inoltre, è possibile creare una codifica personalizzata definendo una classe che deriva da Encoding ed eseguendo l'override dei relativi membri.In addition, you can create a custom encoding by defining a class that derives from Encoding and overriding its members.

Note sulla piattaforma: .NET CorePlatform Notes: .NET Core

Per impostazione predefinita, .NET Core non rende disponibili le codifiche delle tabelle codici diverse dalla tabella codice 28591 e le codifiche Unicode, ad esempio UTF-8 e UTF-16.By default, .NET Core does not make available any code page encodings other than code page 28591 and the Unicode encodings, such as UTF-8 and UTF-16. È tuttavia possibile aggiungere all'app le codifiche delle tabelle codici presenti nelle app di Windows standard destinate a .NET.However, you can add the code page encodings found in standard Windows apps that target .NET to your app. Per informazioni complete, vedere l'argomento CodePagesEncodingProvider .For complete information, see the CodePagesEncodingProvider topic.

Selezione di una classe EncodingSelecting an Encoding Class

Se è possibile scegliere la codifica che verrà usata dall'applicazione, è opportuno usare una codifica Unicode, preferibilmente UTF8Encoding o UnicodeEncoding.If you have the opportunity to choose the encoding to be used by your application, you should use a Unicode encoding, preferably either UTF8Encoding or UnicodeEncoding. .NET supporta anche una terza codifica Unicode, vale a dire UTF32Encoding.(.NET also supports a third Unicode encoding, UTF32Encoding.)

Se si prevede di usare una codifica ASCII (ASCIIEncoding), scegliere invece UTF8Encoding .If you are planning to use an ASCII encoding (ASCIIEncoding), choose UTF8Encoding instead. Le due codifiche sono identiche per il set di caratteri ASCII, ma UTF8Encoding offre i vantaggi seguenti:The two encodings are identical for the ASCII character set, but UTF8Encoding has the following advantages:

  • Può rappresentare ogni carattere Unicode, mentre ASCIIEncoding supporta solo i valori dei caratteri Unicode valori compresi tra U+0000 e U+007F.It can represent every Unicode character, whereas ASCIIEncoding supports only the Unicode character values between U+0000 and U+007F.

  • Fornisce il rilevamento errori e una migliore sicurezza.It provides error detection and better security.

  • È stata ottimizzata per essere il più veloce possibile e dovrebbe essere più veloce di qualsiasi altra codifica.It has been tuned to be as fast as possible and should be faster than any other encoding. Anche per il contenuto interamente ASCII, le operazioni eseguite con UTF8Encoding sono più veloci delle operazioni eseguite con ASCIIEncoding.Even for content that is entirely ASCII, operations performed with UTF8Encoding are faster than operations performed with ASCIIEncoding.

È consigliabile usare ASCIIEncoding solo per le applicazioni legacy.You should consider using ASCIIEncoding only for legacy applications. Tuttavia, anche per le applicazioni legacy, UTF8Encoding potrebbe essere una scelta migliore per i motivi seguenti (presupponendo le impostazioni predefinite):However, even for legacy applications, UTF8Encoding might be a better choice for the following reasons (assuming default settings):

  • Se l'applicazione include contenuto non esclusivamente ASCII e lo codifica con ASCIIEncoding, ogni carattere non ASCII viene codificato come punto interrogativo (?).If your application has content that is not strictly ASCII and encodes it with ASCIIEncoding, each non-ASCII character encodes as a question mark (?). Se l'applicazione quindi decodifica questi dati, le informazioni vengono perse.If the application then decodes this data, the information is lost.

  • Se l'applicazione include contenuto non esclusivamente ASCII e lo codifica con UTF8Encoding, il risultato appare incomprensibile se interpretato come ASCII.If your application has content that is not strictly ASCII and encodes it with UTF8Encoding, the result seems unintelligible if interpreted as ASCII. Tuttavia, se l'applicazione usa poi un decodificatore UTF-8 per decodificare questi dati, i dati eseguono correttamente un round trip.However, if the application then uses a UTF-8 decoder to decode this data, the data performs a round trip successfully.

In un'applicazione Web, i caratteri inviati al client in risposta a una richiesta Web dovrebbero rispecchiare la codifica usata nel client.In a web application, characters sent to the client in response to a web request should reflect the encoding used on the client. Nella maggior parte dei casi, è opportuno impostare la proprietà HttpResponse.ContentEncoding sul valore restituito dalla proprietà HttpRequest.ContentEncoding per visualizzare il testo nella codifica prevista dall'utente.In most cases, you should set the HttpResponse.ContentEncoding property to the value returned by the HttpRequest.ContentEncoding property to display text in the encoding that the user expects.

Uso di un oggetto di codificaUsing an Encoding Object

Un codificatore converte una stringa di caratteri (per lo più caratteri Unicode) nell'equivalente numerico (byte).An encoder converts a string of characters (most commonly, Unicode characters) to its numeric (byte) equivalent. Ad esempio, è possibile usare un codificatore ASCII per convertire i caratteri Unicode in ASCII e poterli visualizzare nella console.For example, you might use an ASCII encoder to convert Unicode characters to ASCII so that they can be displayed at the console. Per eseguire la conversione, si chiama il metodo Encoding.GetBytes .To perform the conversion, you call the Encoding.GetBytes method. Per determinare il numero di byte necessari per archiviare i caratteri codificati prima di eseguire la codifica, è possibile chiamare il metodo GetByteCount .If you want to determine how many bytes are needed to store the encoded characters before performing the encoding, you can call the GetByteCount method.

L'esempio seguente usa una singola matrice di byte per codificare le stringhe in due operazioni distinte.The following example uses a single byte array to encode strings in two separate operations. Gestisce un indice che indica la posizione iniziale nella matrice di byte per il set successivo di byte con codifica ASCII.It maintains an index that indicates the starting position in the byte array for the next set of ASCII-encoded bytes. Chiama il metodo ASCIIEncoding.GetByteCount(String) per assicurarsi che la matrice di byte sia grande abbastanza da contenere la stringa codificata.It calls the ASCIIEncoding.GetByteCount(String) method to ensure that the byte array is large enough to accommodate the encoded string. Chiama quindi il metodo ASCIIEncoding.GetBytes(String, Int32, Int32, Byte[], Int32) per codificare i caratteri nella stringa.It then calls the ASCIIEncoding.GetBytes(String, Int32, Int32, Byte[], Int32) method to encode the characters in the string.

using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      string[] strings= { "This is the first sentence. ", 
                          "This is the second sentence. " };
      Encoding asciiEncoding = Encoding.ASCII;
      
      // Create array of adequate size.
      byte[] bytes = new byte[49];
      // Create index for current position of array.
      int index = 0;
      
      Console.WriteLine("Strings to encode:");
      foreach (var stringValue in strings) {
         Console.WriteLine("   {0}", stringValue);
         
         int count = asciiEncoding.GetByteCount(stringValue);
         if (count + index >=  bytes.Length)
            Array.Resize(ref bytes, bytes.Length + 50);

         int written = asciiEncoding.GetBytes(stringValue, 0, 
                                              stringValue.Length, 
                                              bytes, index);    
    
         index = index + written; 
      } 
      Console.WriteLine("\nEncoded bytes:");
      Console.WriteLine("{0}", ShowByteValues(bytes, index));
      Console.WriteLine();
      
      // Decode Unicode byte array to a string.
      string newString = asciiEncoding.GetString(bytes, 0, index);
      Console.WriteLine("Decoded: {0}", newString);
   }
   
   private static string ShowByteValues(byte[] bytes, int last ) 
   {
      string returnString = "   ";
      for (int ctr = 0; ctr <= last - 1; ctr++) {
         if (ctr % 20 == 0)
            returnString += "\n   ";
         returnString += String.Format("{0:X2} ", bytes[ctr]);
      }
      return returnString;
   }
}
// The example displays the following output:
//       Strings to encode:
//          This is the first sentence.
//          This is the second sentence.
//       
//       Encoded bytes:
//       
//          54 68 69 73 20 69 73 20 74 68 65 20 66 69 72 73 74 20 73 65
//          6E 74 65 6E 63 65 2E 20 54 68 69 73 20 69 73 20 74 68 65 20
//          73 65 63 6F 6E 64 20 73 65 6E 74 65 6E 63 65 2E 20
//       
//       Decoded: This is the first sentence. This is the second sentence.
Imports System.Text

Module Example
   Public Sub Main()
      Dim strings() As String = { "This is the first sentence. ", 
                                  "This is the second sentence. " }
      Dim asciiEncoding As Encoding = Encoding.ASCII
      
      ' Create array of adequate size.
      Dim bytes(50) As Byte
      ' Create index for current position of array.
      Dim index As Integer = 0
      
      Console.WriteLine("Strings to encode:")
      For Each stringValue In strings
         Console.WriteLine("   {0}", stringValue)
         
         Dim count As Integer = asciiEncoding.GetByteCount(stringValue)
         If count + index >=  bytes.Length Then
            Array.Resize(bytes, bytes.Length + 50)
         End If
         Dim written As Integer = asciiEncoding.GetBytes(stringValue, 0, 
                                                         stringValue.Length, 
                                                         bytes, index)    
    
         index = index + written 
      Next 
      Console.WriteLine()
      Console.WriteLine("Encoded bytes:")
      Console.WriteLine("{0}", ShowByteValues(bytes, index))
      Console.WriteLine()
      
      ' Decode Unicode byte array to a string.
      Dim newString As String = asciiEncoding.GetString(bytes, 0, index)
      Console.WriteLine("Decoded: {0}", newString)
   End Sub
   
   Private Function ShowByteValues(bytes As Byte(), last As Integer) As String
      Dim returnString As String = "   "
      For ctr As Integer = 0 To last - 1
         If ctr Mod 20 = 0 Then returnString += vbCrLf + "   "
         returnString += String.Format("{0:X2} ", bytes(ctr))
      Next
      Return returnString
   End Function
End Module
' The example displays the following output:
'       Strings to encode:
'          This is the first sentence.
'          This is the second sentence.
'       
'       Encoded bytes:
'       
'          54 68 69 73 20 69 73 20 74 68 65 20 66 69 72 73 74 20 73 65
'          6E 74 65 6E 63 65 2E 20 54 68 69 73 20 69 73 20 74 68 65 20
'          73 65 63 6F 6E 64 20 73 65 6E 74 65 6E 63 65 2E 20
'       
'       Decoded: This is the first sentence. This is the second sentence.

Un decodificatore converte una matrice di byte che rispecchia una particolare codifica dei caratteri in un set di caratteri, in una matrice di caratteri o in una stringa.A decoder converts a byte array that reflects a particular character encoding into a set of characters, either in a character array or in a string. Per decodificare una matrice di byte in una matrice di caratteri, si chiama il metodo Encoding.GetChars .To decode a byte array into a character array, you call the Encoding.GetChars method. Per decodificare una matrice di byte in una stringa, si chiama il metodo GetString .To decode a byte array into a string, you call the GetString method. Per determinare il numero di caratteri necessari per archiviare i byte decodificati prima di eseguire la decodifica, è possibile chiamare il metodo GetCharCount .If you want to determine how many characters are needed to store the decoded bytes before performing the decoding, you can call the GetCharCount method.

L'esempio seguente codifica tre stringhe e quindi le decodifica in una singola matrice di caratteri.The following example encodes three strings and then decodes them into a single array of characters. Gestisce un indice che indica la posizione iniziale nella matrice di caratteri per il set successivo di caratteri decodificati.It maintains an index that indicates the starting position in the character array for the next set of decoded characters. Chiama il metodo GetCharCount per assicurarsi che la matrice di caratteri sia grande abbastanza da contenere tutti i caratteri decodificati.It calls the GetCharCount method to ensure that the character array is large enough to accommodate all the decoded characters. Chiama quindi il metodo ASCIIEncoding.GetChars(Byte[], Int32, Int32, Char[], Int32) per decodificare la matrice di byte.It then calls the ASCIIEncoding.GetChars(Byte[], Int32, Int32, Char[], Int32) method to decode the byte array.

using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      string[] strings = { "This is the first sentence. ", 
                           "This is the second sentence. ",
                           "This is the third sentence. " };
      Encoding asciiEncoding = Encoding.ASCII;
      // Array to hold encoded bytes.
      byte[] bytes;
      // Array to hold decoded characters.
      char[] chars = new char[50];
      // Create index for current position of character array.
      int index = 0;     
      
      foreach (var stringValue in strings) {
         Console.WriteLine("String to Encode: {0}", stringValue);
         // Encode the string to a byte array.
         bytes = asciiEncoding.GetBytes(stringValue);
         // Display the encoded bytes.
         Console.Write("Encoded bytes: ");
         for (int ctr = 0; ctr < bytes.Length; ctr++)
            Console.Write(" {0}{1:X2}", 
                          ctr % 20 == 0 ? Environment.NewLine : "", 
                          bytes[ctr]);
         Console.WriteLine();

         // Decode the bytes to a single character array.
         int count = asciiEncoding.GetCharCount(bytes);
         if (count + index >=  chars.Length)
            Array.Resize(ref chars, chars.Length + 50);

         int written = asciiEncoding.GetChars(bytes, 0, 
                                              bytes.Length, 
                                              chars, index);              
         index = index + written;
         Console.WriteLine();       
      }
      
      // Instantiate a single string containing the characters.
      string decodedString = new string(chars, 0, index - 1);
      Console.WriteLine("Decoded string: ");
      Console.WriteLine(decodedString);
   }
}
// The example displays the following output:
//    String to Encode: This is the first sentence.
//    Encoded bytes:
//    54 68 69 73 20 69 73 20 74 68 65 20 66 69 72 73 74 20 73 65
//    6E 74 65 6E 63 65 2E 20
//    
//    String to Encode: This is the second sentence.
//    Encoded bytes:
//    54 68 69 73 20 69 73 20 74 68 65 20 73 65 63 6F 6E 64 20 73
//    65 6E 74 65 6E 63 65 2E 20
//    
//    String to Encode: This is the third sentence.
//    Encoded bytes:
//    54 68 69 73 20 69 73 20 74 68 65 20 74 68 69 72 64 20 73 65
//    6E 74 65 6E 63 65 2E 20
//    
//    Decoded string:
//    This is the first sentence. This is the second sentence. This is the third sentence.
Imports System.Text

Module Example
   Public Sub Main()
      Dim strings() As String = { "This is the first sentence. ", 
                                  "This is the second sentence. ",
                                  "This is the third sentence. " }
      Dim asciiEncoding As Encoding = Encoding.ASCII
      ' Array to hold encoded bytes.
      Dim bytes() As Byte
      ' Array to hold decoded characters.
      Dim chars(50) As Char
      ' Create index for current position of character array.
      Dim index As Integer     
      
      For Each stringValue In strings
         Console.WriteLine("String to Encode: {0}", stringValue)
         ' Encode the string to a byte array.
         bytes = asciiEncoding.GetBytes(stringValue)
         ' Display the encoded bytes.
         Console.Write("Encoded bytes: ")
         For ctr As Integer = 0 To bytes.Length - 1
            Console.Write(" {0}{1:X2}", If(ctr Mod 20 = 0, vbCrLf, ""), 
                                        bytes(ctr))
         Next         
         Console.WriteLine()

         ' Decode the bytes to a single character array.
         Dim count As Integer = asciiEncoding.GetCharCount(bytes)
         If count + index >=  chars.Length Then
            Array.Resize(chars, chars.Length + 50)
         End If
         Dim written As Integer = asciiEncoding.GetChars(bytes, 0, 
                                                         bytes.Length, 
                                                         chars, index)              
         index = index + written
         Console.WriteLine()       
      Next
      
      ' Instantiate a single string containing the characters.
      Dim decodedString As New String(chars, 0, index - 1)
      Console.WriteLine("Decoded string: ")
      Console.WriteLine(decodedString)
   End Sub
End Module
' The example displays the following output:
'    String to Encode: This is the first sentence.
'    Encoded bytes:
'    54 68 69 73 20 69 73 20 74 68 65 20 66 69 72 73 74 20 73 65
'    6E 74 65 6E 63 65 2E 20
'    
'    String to Encode: This is the second sentence.
'    Encoded bytes:
'    54 68 69 73 20 69 73 20 74 68 65 20 73 65 63 6F 6E 64 20 73
'    65 6E 74 65 6E 63 65 2E 20
'    
'    String to Encode: This is the third sentence.
'    Encoded bytes:
'    54 68 69 73 20 69 73 20 74 68 65 20 74 68 69 72 64 20 73 65
'    6E 74 65 6E 63 65 2E 20
'    
'    Decoded string:
'    This is the first sentence. This is the second sentence. This is the third sentence.

I metodi di codifica e di decodifica di una classe derivata da Encoding sono progettati per funzionare su un set completo di dati, ovvero tutti i dati da codificare o decodificare vengono forniti in una singola chiamata al metodo.The encoding and decoding methods of a class derived from Encoding are designed to work on a complete set of data; that is, all the data to be encoded or decoded is supplied in a single method call. In alcuni casi, tuttavia, i dati sono disponibili in un flusso e i dati da codificare o decodificare potrebbero essere disponibili solo in operazioni di lettura distinte.However, in some cases, data is available in a stream, and the data to be encoded or decoded may be available only from separate read operations. Ciò richiede che l'operazione di codifica o decodifica ricordi qualsiasi stato salvato dalla chiamata precedente.This requires the encoding or decoding operation to remember any saved state from its previous invocation. I metodi delle classi derivate da Encoder e Decoder possono gestire le operazioni di codifica e decodifica di operazioni che comprendono più chiamate ai metodi.Methods of classes derived from Encoder and Decoder are able to handle encoding and decoding operations that span multiple method calls.

Un oggetto Encoder per una particolare codifica è disponibile nella proprietà Encoding.GetEncoder di tale codifica.An Encoder object for a particular encoding is available from that encoding's Encoding.GetEncoder property. Un oggetto Decoder per una particolare codifica è disponibile nella proprietà Encoding.GetDecoder di tale codifica.A Decoder object for a particular encoding is available from that encoding's Encoding.GetDecoder property. Per le operazioni di decodifica, tenere presente che le classi derivate da Decoder includono un metodo Decoder.GetChars , ma non dispongono di un metodo corrispondente a Encoding.GetString.For decoding operations, note that classes derived from Decoder include a Decoder.GetChars method, but they do not have a method that corresponds to Encoding.GetString.

L'esempio seguente illustra la differenza tra l'uso dei metodi Encoding.GetChars e Decoder.GetChars per la decodifica di una matrice di byte Unicode.The following example illustrates the difference between using the Encoding.GetChars and Decoder.GetChars methods for decoding a Unicode byte array. L'esempio codifica in un file una stringa che contiene alcuni caratteri Unicode e quindi usa i due metodi di decodifica per decodificarli dieci byte alla volta.The example encodes a string that contains some Unicode characters to a file, and then uses the two decoding methods to decode them ten bytes at a time. Una coppia di surrogati presente nel decimo e nell'undicesimo byte viene decodificata in chiamate ai metodi distinte.Because a surrogate pair occurs in the tenth and eleventh bytes, it is decoded in separate method calls. Come mostra l'output, il metodo Encoding.GetChars non è in grado di decodificare correttamente i byte e li sostituisce invece con U+FFFD (REPLACEMENT CHARACTER).As the output shows, the Encoding.GetChars method is not able to correctly decode the bytes and instead replaces them with U+FFFD (REPLACEMENT CHARACTER). D'altra parte, il Decoder.GetChars metodo è in grado di decodificare correttamente la matrice di byte per ottenere la stringa originale.On the other hand, the Decoder.GetChars method is able to successfully decode the byte array to get the original string.

using System;
using System.IO;
using System.Text;

public class Example
{
   public static void Main()
   {
      // Use default replacement fallback for invalid encoding.
      UnicodeEncoding enc = new UnicodeEncoding(true, false, false);
      
      // Define a string with various Unicode characters.
      string str1 = "AB YZ 19 \uD800\udc05 \u00e4"; 
      str1 += "Unicode characters. \u00a9 \u010C s \u0062\u0308"; 
      Console.WriteLine("Created original string...\n");
      
      // Convert string to byte array.                     
      byte[] bytes = enc.GetBytes(str1);
       
      FileStream fs = File.Create(@".\characters.bin");
      BinaryWriter bw = new BinaryWriter(fs);
      bw.Write(bytes);
      bw.Close();
      
      // Read bytes from file.
      FileStream fsIn = File.OpenRead(@".\characters.bin");
      BinaryReader br = new BinaryReader(fsIn);
      
      const int count = 10;            // Number of bytes to read at a time. 
      byte[] bytesRead = new byte[10]; // Buffer (byte array).
      int read;                        // Number of bytes actually read. 
      string str2 = String.Empty;      // Decoded string.

      // Try using Encoding object for all operations.
      do { 
         read = br.Read(bytesRead, 0, count);
         str2 += enc.GetString(bytesRead, 0, read); 
      } while (read == count);
      br.Close();
      Console.WriteLine("Decoded string using UnicodeEncoding.GetString()...");
      CompareForEquality(str1, str2);
      Console.WriteLine();
      
      // Use Decoder for all operations.
      fsIn = File.OpenRead(@".\characters.bin");
      br = new BinaryReader(fsIn);
      Decoder decoder = enc.GetDecoder();
      char[] chars = new char[50];
      int index = 0;                   // Next character to write in array.
      int written = 0;                 // Number of chars written to array.
      do { 
         read = br.Read(bytesRead, 0, count);
         if (index + decoder.GetCharCount(bytesRead, 0, read) - 1 >= chars.Length) 
            Array.Resize(ref chars, chars.Length + 50);

         written = decoder.GetChars(bytesRead, 0, read, chars, index);
         index += written;                          
      } while (read == count);
      br.Close();            
      // Instantiate a string with the decoded characters.
      string str3 = new String(chars, 0, index); 
      Console.WriteLine("Decoded string using UnicodeEncoding.Decoder.GetString()...");
      CompareForEquality(str1, str3); 
   }

   private static void CompareForEquality(string original, string decoded)
   {
      bool result = original.Equals(decoded);
      Console.WriteLine("original = decoded: {0}", 
                        original.Equals(decoded, StringComparison.Ordinal));
      if (! result) {
         Console.WriteLine("Code points in original string:");
         foreach (var ch in original)
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));
         Console.WriteLine();
         
         Console.WriteLine("Code points in decoded string:");
         foreach (var ch in decoded)
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));
         Console.WriteLine();
      }
   }
}
// The example displays the following output:
//    Created original string...
//    
//    Decoded string using UnicodeEncoding.GetString()...
//    original = decoded: False
//    Code points in original string:
//    0041 0042 0020 0059 005A 0020 0031 0039 0020 D800 DC05 0020 00E4 0055 006E 0069 0063 006F
//    0064 0065 0020 0063 0068 0061 0072 0061 0063 0074 0065 0072 0073 002E 0020 00A9 0020 010C
//    0020 0073 0020 0062 0308
//    Code points in decoded string:
//    0041 0042 0020 0059 005A 0020 0031 0039 0020 FFFD FFFD 0020 00E4 0055 006E 0069 0063 006F
//    0064 0065 0020 0063 0068 0061 0072 0061 0063 0074 0065 0072 0073 002E 0020 00A9 0020 010C
//    0020 0073 0020 0062 0308
//    
//    Decoded string using UnicodeEncoding.Decoder.GetString()...
//    original = decoded: True
Imports System.IO
Imports System.Text

Module Example
   Public Sub Main()
      ' Use default replacement fallback for invalid encoding.
      Dim enc As New UnicodeEncoding(True, False, False)
      
      ' Define a string with various Unicode characters.
      Dim str1 As String = String.Format("AB YZ 19 {0}{1} {2}", 
                                         ChrW(&hD800), ChrW(&hDC05), ChrW(&h00e4))
      str1 += String.Format("Unicode characters. {0} {1} s {2}{3}", 
                            ChrW(&h00a9), ChrW(&h010C), ChrW(&h0062), ChrW(&h0308))
      Console.WriteLine("Created original string...")
      Console.WriteLine()
      
      ' Convert string to byte array.                     
      Dim bytes() As Byte = enc.GetBytes(str1)
       
      Dim fs As FileStream = File.Create(".\characters.bin")
      Dim bw As New BinaryWriter(fs)
      bw.Write(bytes)
      bw.Close()
      
      ' Read bytes from file.
      Dim fsIn As FileStream = File.OpenRead(".\characters.bin")
      Dim br As New BinaryReader(fsIn)
      
      Const count As Integer = 10      ' Number of bytes to read at a time. 
      Dim bytesRead(9) As Byte         ' Buffer (byte array).
      Dim read As Integer              ' Number of bytes actually read. 
      Dim str2 As String = ""          ' Decoded string.

      ' Try using Encoding object for all operations.
      Do 
         read = br.Read(bytesRead, 0, count)
         str2 += enc.GetString(bytesRead, 0, read) 
      Loop While read = count
      br.Close()
      Console.WriteLine("Decoded string using UnicodeEncoding.GetString()...")
      CompareForEquality(str1, str2)
      Console.WriteLine()
      
      ' Use Decoder for all operations.
      fsIn = File.OpenRead(".\characters.bin")
      br = New BinaryReader(fsIn)
      Dim decoder As Decoder = enc.GetDecoder()
      Dim chars(50) As Char
      Dim index As Integer = 0         ' Next character to write in array.
      Dim written As Integer = 0       ' Number of chars written to array.
      Do 
         read = br.Read(bytesRead, 0, count)
         If index + decoder.GetCharCount(bytesRead, 0, read) - 1 >= chars.Length Then 
            Array.Resize(chars, chars.Length + 50)
         End If   
         written = decoder.GetChars(bytesRead, 0, read, chars, index)
         index += written                          
      Loop While read = count
      br.Close()            
      ' Instantiate a string with the decoded characters.
      Dim str3 As New String(chars, 0, index) 
      Console.WriteLine("Decoded string using UnicodeEncoding.Decoder.GetString()...")
      CompareForEquality(str1, str3) 
   End Sub
   
   Private Sub CompareForEquality(original As String, decoded As String)
      Dim result As Boolean = original.Equals(decoded)
      Console.WriteLine("original = decoded: {0}", 
                        original.Equals(decoded, StringComparison.Ordinal))
      If Not result Then
         Console.WriteLine("Code points in original string:")
         For Each ch In original
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
         Next
         Console.WriteLine()
         
         Console.WriteLine("Code points in decoded string:")
         For Each ch In decoded
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
         Next
         Console.WriteLine()
      End If
   End Sub
End Module
' The example displays the following output:
'    Created original string...
'    
'    Decoded string using UnicodeEncoding.GetString()...
'    original = decoded: False
'    Code points in original string:
'    0041 0042 0020 0059 005A 0020 0031 0039 0020 D800 DC05 0020 00E4 0055 006E 0069 0063 006F
'    0064 0065 0020 0063 0068 0061 0072 0061 0063 0074 0065 0072 0073 002E 0020 00A9 0020 010C
'    0020 0073 0020 0062 0308
'    Code points in decoded string:
'    0041 0042 0020 0059 005A 0020 0031 0039 0020 FFFD FFFD 0020 00E4 0055 006E 0069 0063 006F
'    0064 0065 0020 0063 0068 0061 0072 0061 0063 0074 0065 0072 0073 002E 0020 00A9 0020 010C
'    0020 0073 0020 0062 0308
'    
'    Decoded string using UnicodeEncoding.Decoder.GetString()...
'    original = decoded: True

Scelta di una strategia di fallbackChoosing a Fallback Strategy

Quando un metodo tenta di codificare o decodificare un carattere, ma non esiste alcun mapping, deve implementare una strategia di fallback che determina come gestire il mapping non riuscito.When a method tries to encode or decode a character but no mapping exists, it must implement a fallback strategy that determines how the failed mapping should be handled. Esistono tre tipi di strategie di fallback:There are three types of fallback strategies:

  • Best-Fit FallbackBest-fit fallback

  • Replacement FallbackReplacement fallback

  • Exception FallbackException fallback

Importante

I problemi più comuni nelle operazioni di codifica si verificano quando non è possibile eseguire il mapping di un carattere Unicode a una particolare codifica della tabella codici.The most common problems in encoding operations occur when a Unicode character cannot be mapped to a particular code page encoding. I problemi più comuni nelle operazioni di decodifica si verificano quando sequenze di byte non valide non possono essere convertite in caratteri Unicode validi.The most common problems in decoding operations occur when invalid byte sequences cannot be translated into valid Unicode characters. Per questi motivi, è opportuno conoscere la strategia di fallback usata da un oggetto di codifica specifico.For these reasons, you should know which fallback strategy a particular encoding object uses. Quando è possibile, è consigliabile specificare la strategia di fallback usata da un oggetto di codifica quando si crea un'istanza dell'oggetto.Whenever possible, you should specify the fallback strategy used by an encoding object when you instantiate the object.

Best-Fit FallbackBest-Fit Fallback

Quando un carattere non ha una corrispondenza esatta nella codifica di destinazione, il codificatore può provare a eseguirne il mapping a un carattere simile.When a character does not have an exact match in the target encoding, the encoder can try to map it to a similar character. Il fallback con mapping più appropriato è principalmente un problema di codifica più che di decodifica.(Best-fit fallback is mostly an encoding rather than a decoding issue. Esistono pochissime tabelle codici contenenti caratteri di cui non è possibile eseguire correttamente il mapping a Unicode. Il fallback con mapping più appropriato è quello predefinito per le codifiche della tabella codici e Double Byte Character Set recuperate dagli overload Encoding.GetEncoding(Int32) e Encoding.GetEncoding(String).There are very few code pages that contain characters that cannot be successfully mapped to Unicode.) Best-fit fallback is the default for code page and double-byte character set encodings that are retrieved by the Encoding.GetEncoding(Int32) and Encoding.GetEncoding(String) overloads.

Nota

In teoria, le classi Encoding Unicode fornite in .NET (UTF8Encoding, UnicodeEncoding e UTF32Encoding) supportano ogni carattere di ogni set di caratteri e quindi possono essere usate per eliminare i problemi di fallback con mapping più appropriato.In theory, the Unicode encoding classes provided in .NET (UTF8Encoding, UnicodeEncoding, and UTF32Encoding) support every character in every character set, so they can be used to eliminate best-fit fallback issues.

Le strategie di fallback con mapping più appropriato sono diverse a seconda delle tabelle codici.Best-fit strategies vary for different code pages. Ad esempio, per alcune tabelle codici, dei caratteri latini a larghezza intera viene eseguito il mapping ai caratteri latini a metà larghezza più comuni.For example, for some code pages, full-width Latin characters map to the more common half-width Latin characters. Per altre tabelle codici, questo mapping non viene eseguito.For other code pages, this mapping is not made. Anche se si adotta una strategia aggressiva basata sul mapping più appropriato, per alcuni caratteri in alcune codifiche non è concepibile un mapping appropriato.Even under an aggressive best-fit strategy, there is no imaginable fit for some characters in some encodings. Ad esempio, per un ideogramma cinese non esistono mapping ragionevoli alla tabella codici 1252.For example, a Chinese ideograph has no reasonable mapping to code page 1252. In questo caso, viene usata una stringa di sostituzione.In this case, a replacement string is used. Per impostazione predefinita, questa stringa è semplicemente un punto interrogativo (QUESTION MARK, U+003F).By default, this string is just a single QUESTION MARK (U+003F).

Nota

Le strategie di fallback con mapping più appropriato non sono documentate in dettaglio.Best-fit strategies are not documented in detail. Diverse tabelle codici sono tuttavia documentate nel sito Web di Unicode Consortium.However, several code pages are documented at the Unicode Consortium's website. Esaminare il file readme.txt in tale cartella per una descrizione di come interpretare i file di mapping.Please review the readme.txt file in that folder for a description of how to interpret the mapping files.

L'esempio seguente usa la tabella codici 1252 (la tabella codici di Windows per le lingue dell'Europa occidentale) per illustrare il mapping più appropriato e i relativi svantaggi.The following example uses code page 1252 (the Windows code page for Western European languages) to illustrate best-fit mapping and its drawbacks. Viene usato il metodo Encoding.GetEncoding(Int32) per recuperare un oggetto di codifica per la tabella codici 1252.The Encoding.GetEncoding(Int32) method is used to retrieve an encoding object for code page 1252. Per impostazione predefinita, usa il mapping più appropriato per i caratteri Unicode che non supporta.By default, it uses a best-fit mapping for Unicode characters that it does not support. L'esempio crea un'istanza di una stringa che contiene tre caratteri non ASCII, CIRCLED LATIN CAPITAL LETTER S (U+24C8), SUPERSCRIPT FIVE (U+2075) e INFINITY (U+221E), separati da spazi.The example instantiates a string that contains three non-ASCII characters - CIRCLED LATIN CAPITAL LETTER S (U+24C8), SUPERSCRIPT FIVE (U+2075), and INFINITY (U+221E) - separated by spaces. Come mostra l'output del seguente esempio, quando la stringa viene codificata, i tre caratteri originali diversi dallo spazio vengono sostituiti da QUESTION MARK (U+003F), DIGIT FIVE (U+0035) e DIGIT EIGHT (U+0038).As the output from the example shows, when the string is encoded, the three original non-space characters are replaced by QUESTION MARK (U+003F), DIGIT FIVE (U+0035), and DIGIT EIGHT (U+0038). DIGIT EIGHT è una sostituzione del tutto inadeguata per il carattere INFINITY non supportato e QUESTION MARK indica che non è disponibile alcun mapping per il carattere originale.DIGIT EIGHT is a particularly poor replacement for the unsupported INFINITY character, and QUESTION MARK indicates that no mapping was available for the original character.

using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      // Get an encoding for code page 1252 (Western Europe character set).
      Encoding cp1252 = Encoding.GetEncoding(1252);
      
      // Define and display a string.
      string str = "\u24c8 \u2075 \u221e";
      Console.WriteLine("Original string: " + str);
      Console.Write("Code points in string: ");
      foreach (var ch in str)
         Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));

      Console.WriteLine("\n");   
      
      // Encode a Unicode string.
      Byte[] bytes = cp1252.GetBytes(str);
      Console.Write("Encoded bytes: ");
      foreach (byte byt in bytes)
         Console.Write("{0:X2} ", byt);
      Console.WriteLine("\n");
            
      // Decode the string.
      string str2 = cp1252.GetString(bytes);
      Console.WriteLine("String round-tripped: {0}", str.Equals(str2));
      if (! str.Equals(str2)) {
         Console.WriteLine(str2);
         foreach (var ch in str2)
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));
      }
   }
}
// The example displays the following output:
//       Original string: Ⓢ ⁵ ∞
//       Code points in string: 24C8 0020 2075 0020 221E
//       
//       Encoded bytes: 3F 20 35 20 38
//       
//       String round-tripped: False
//       ? 5 8
//       003F 0020 0035 0020 0038
Imports System.Text

Module Example
   Public Sub Main()
      ' Get an encoding for code page 1252 (Western Europe character set).
      Dim cp1252 As Encoding = Encoding.GetEncoding(1252)
      
      ' Define and display a string.
      Dim str As String = String.Format("{0} {1} {2}", ChrW(&h24c8), ChrW(&H2075), ChrW(&h221E))
      Console.WriteLine("Original string: " + str)
      Console.Write("Code points in string: ")
      For Each ch In str
         Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
      Next
      Console.WriteLine()   
      Console.WriteLine()
      
      ' Encode a Unicode string.
      Dim bytes() As Byte = cp1252.GetBytes(str)
      Console.Write("Encoded bytes: ")
      For Each byt In bytes
         Console.Write("{0:X2} ", byt)
      Next
      Console.WriteLine()
      Console.WriteLine()
      
      ' Decode the string.
      Dim str2 As String = cp1252.GetString(bytes)
      Console.WriteLine("String round-tripped: {0}", str.Equals(str2))
      If Not str.Equals(str2) Then
         Console.WriteLine(str2)
         For Each ch In str2
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
         Next
      End If
   End Sub
End Module
' The example displays the following output:
'       Original string: Ⓢ ⁵ ∞
'       Code points in string: 24C8 0020 2075 0020 221E
'       
'       Encoded bytes: 3F 20 35 20 38
'       
'       String round-tripped: False
'       ? 5 8
'       003F 0020 0035 0020 0038

Il mapping più appropriato è il comportamento predefinito per un oggetto Encoding che codifica i dati Unicode come dati della tabella codici. Esistono applicazioni legacy che si basano su questo comportamento.Best-fit mapping is the default behavior for an Encoding object that encodes Unicode data into code page data, and there are legacy applications that rely on this behavior. Tuttavia, per motivi di sicurezza, per la maggior parte delle nuove applicazioni si dovrebbe evitare il comportamento basato sul mapping più appropriato.However, most new applications should avoid best-fit behavior for security reasons. Ad esempio, le applicazioni non dovrebbero inserire un nome di dominio tramite una codifica con mapping più appropriato.For example, applications should not put a domain name through a best-fit encoding.

Nota

Si può anche implementare un mapping basato sul fallback più appropriato personalizzato per una codifica.You can also implement a custom best-fit fallback mapping for an encoding. Per altre informazioni, vedere la sezione Implementing a Custom Fallback Strategy .For more information, see the Implementing a Custom Fallback Strategy section.

Se il fallback con mapping più appropriato è quello predefinito per un oggetto di codifica, è possibile scegliere un'altra strategia di fallback quando si recupera un oggetto Encoding chiamando l'overload Encoding.GetEncoding(Int32, EncoderFallback, DecoderFallback) o Encoding.GetEncoding(String, EncoderFallback, DecoderFallback) .If best-fit fallback is the default for an encoding object, you can choose another fallback strategy when you retrieve an Encoding object by calling the Encoding.GetEncoding(Int32, EncoderFallback, DecoderFallback) or Encoding.GetEncoding(String, EncoderFallback, DecoderFallback) overload. La sezione seguente include un esempio che sostituisce con un asterisco (*) ogni carattere di cui non è possibile eseguire il mapping alla tabella codici 1252.The following section includes an example that replaces each character that cannot be mapped to code page 1252 with an asterisk (*).

using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      Encoding cp1252r = Encoding.GetEncoding(1252, 
                                  new EncoderReplacementFallback("*"),
                                  new DecoderReplacementFallback("*"));
      
      string str1 = "\u24C8 \u2075 \u221E";
      Console.WriteLine(str1);
      foreach (var ch in str1)
         Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));

      Console.WriteLine();

      byte[] bytes = cp1252r.GetBytes(str1);
      string str2 = cp1252r.GetString(bytes);
      Console.WriteLine("Round-trip: {0}", str1.Equals(str2));
      if (! str1.Equals(str2)) {
         Console.WriteLine(str2);
         foreach (var ch in str2)
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));

         Console.WriteLine();
      } 
   }
}
// The example displays the following output:
//       Ⓢ ⁵ ∞
//       24C8 0020 2075 0020 221E
//       Round-trip: False
//       * * *
//       002A 0020 002A 0020 002A
Imports System.Text

Module Example
   Public Sub Main()
      Dim cp1252r As Encoding = Encoding.GetEncoding(1252, 
                                         New EncoderReplacementFallback("*"),
                                         New DecoderReplacementFallback("*"))
      
      Dim str1 As String = String.Format("{0} {1} {2}", ChrW(&h24C8), ChrW(&h2075), ChrW(&h221E))
      Console.WriteLine(str1)
      For Each ch In str1
         Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
      Next    
      Console.WriteLine()

      Dim bytes() As Byte = cp1252r.GetBytes(str1)
      Dim str2 As String = cp1252r.GetString(bytes)
      Console.WriteLine("Round-trip: {0}", str1.Equals(str2))
      If Not str1.Equals(str2) Then
         Console.WriteLine(str2)
         For Each ch In str2
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
         Next    
         Console.WriteLine()
      End If 
   End Sub
End Module
' The example displays the following output:
'       Ⓢ ⁵ ∞
'       24C8 0020 2075 0020 221E
'       Round-trip: False
'       * * *
'       002A 0020 002A 0020 002A

Replacement FallbackReplacement Fallback

Quando un carattere non ha una corrispondenza esatta nello schema di destinazione e non esiste un carattere appropriato a cui eseguirne il mapping, l'applicazione può specificare una carattere o una stringa di sostituzione.When a character does not have an exact match in the target scheme, but there is no appropriate character that it can be mapped to, the application can specify a replacement character or string. È il comportamento predefinito del decodificatore Unicode, che sostituisce con REPLACEMENT_CHARACTER (U+FFFD) le sequenze a due byte che non può decodificare.This is the default behavior for the Unicode decoder, which replaces any two-byte sequence that it cannot decode with REPLACEMENT_CHARACTER (U+FFFD). È anche il comportamento predefinito della classe ASCIIEncoding , che sostituisce ogni carattere che non può codificare o decodificare con un punto interrogativo.It is also the default behavior of the ASCIIEncoding class, which replaces each character that it cannot encode or decode with a question mark. Il seguente esempio illustra la sostituzione dei caratteri della stringa Unicode dell'esempio precedente.The following example illustrates character replacement for the Unicode string from the previous example. Come mostra l'output, ogni carattere che non può essere decodificato con un byte ASCII viene sostituito da 0x3F, ovvero dal codice ASCII per il punto interrogativo.As the output shows, each character that cannot be decoded into an ASCII byte value is replaced by 0x3F, which is the ASCII code for a question mark.

using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      Encoding enc = Encoding.ASCII;
      
      string str1 = "\u24C8 \u2075 \u221E";
      Console.WriteLine(str1);
      foreach (var ch in str1)
         Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));

      Console.WriteLine("\n");

      // Encode the original string using the ASCII encoder.
      byte[] bytes = enc.GetBytes(str1);
      Console.Write("Encoded bytes: ");
      foreach (var byt in bytes)
         Console.Write("{0:X2} ", byt);
      Console.WriteLine("\n");

      // Decode the ASCII bytes.
      string str2 = enc.GetString(bytes);
      Console.WriteLine("Round-trip: {0}", str1.Equals(str2));
      if (! str1.Equals(str2)) {
         Console.WriteLine(str2);
         foreach (var ch in str2)
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));

         Console.WriteLine();
      } 
   }
}
// The example displays the following output:
//       Ⓢ ⁵ ∞
//       24C8 0020 2075 0020 221E
//       
//       Encoded bytes: 3F 20 3F 20 3F
//       
//       Round-trip: False
//       ? ? ?
//       003F 0020 003F 0020 003F
Imports System.Text

Module Example
   Public Sub Main()
      Dim enc As Encoding = Encoding.Ascii
      
      Dim str1 As String = String.Format("{0} {1} {2}", ChrW(&h24C8), ChrW(&h2075), ChrW(&h221E))
      Console.WriteLine(str1)
      For Each ch In str1
         Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
      Next    
      Console.WriteLine()
      Console.WriteLine() 

      ' Encode the original string using the ASCII encoder.
      Dim bytes() As Byte = enc.GetBytes(str1)
      Console.Write("Encoded bytes: ")
      For Each byt In bytes
         Console.Write("{0:X2} ", byt)
      Next
      Console.WriteLine()
      Console.WriteLine()

      ' Decode the ASCII bytes.
      Dim str2 As String = enc.GetString(bytes)
      Console.WriteLine("Round-trip: {0}", str1.Equals(str2))
      If Not str1.Equals(str2) Then
         Console.WriteLine(str2)
         For Each ch In str2
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
         Next    
         Console.WriteLine()
      End If 
   End Sub
End Module
' The example displays the following output:
'       Ⓢ ⁵ ∞
'       24C8 0020 2075 0020 221E
'       
'       Encoded bytes: 3F 20 3F 20 3F
'       
'       Round-trip: False
'       ? ? ?
'       003F 0020 003F 0020 003F

.NET include le classi EncoderReplacementFallback e DecoderReplacementFallback, che usano una stringa di sostituzione se non è possibile eseguire il mapping esatto di un carattere in un'operazione di codifica o decodifica..NET includes the EncoderReplacementFallback and DecoderReplacementFallback classes, which substitute a replacement string if a character does not map exactly in an encoding or decoding operation. Per impostazione predefinita, questa stringa di sostituzione è un punto interrogativo, ma è possibile chiamare un overload del costruttore di classe per scegliere un'altra stringa.By default, this replacement string is a question mark, but you can call a class constructor overload to choose a different string. In genere, la stringa di sostituzione è costituita da un solo carattere, anche se questo non è un requisito.Typically, the replacement string is a single character, although this is not a requirement. L'esempio seguente modifica il comportamento del codificatore della tabella codici 1252 creando un'istanza dell'oggetto EncoderReplacementFallback che usa un asterisco (*) come stringa di sostituzione.The following example changes the behavior of the code page 1252 encoder by instantiating an EncoderReplacementFallback object that uses an asterisk (*) as a replacement string.

using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      Encoding cp1252r = Encoding.GetEncoding(1252, 
                                  new EncoderReplacementFallback("*"),
                                  new DecoderReplacementFallback("*"));
      
      string str1 = "\u24C8 \u2075 \u221E";
      Console.WriteLine(str1);
      foreach (var ch in str1)
         Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));

      Console.WriteLine();

      byte[] bytes = cp1252r.GetBytes(str1);
      string str2 = cp1252r.GetString(bytes);
      Console.WriteLine("Round-trip: {0}", str1.Equals(str2));
      if (! str1.Equals(str2)) {
         Console.WriteLine(str2);
         foreach (var ch in str2)
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));

         Console.WriteLine();
      } 
   }
}
// The example displays the following output:
//       Ⓢ ⁵ ∞
//       24C8 0020 2075 0020 221E
//       Round-trip: False
//       * * *
//       002A 0020 002A 0020 002A
Imports System.Text

Module Example
   Public Sub Main()
      Dim cp1252r As Encoding = Encoding.GetEncoding(1252, 
                                         New EncoderReplacementFallback("*"),
                                         New DecoderReplacementFallback("*"))
      
      Dim str1 As String = String.Format("{0} {1} {2}", ChrW(&h24C8), ChrW(&h2075), ChrW(&h221E))
      Console.WriteLine(str1)
      For Each ch In str1
         Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
      Next    
      Console.WriteLine()

      Dim bytes() As Byte = cp1252r.GetBytes(str1)
      Dim str2 As String = cp1252r.GetString(bytes)
      Console.WriteLine("Round-trip: {0}", str1.Equals(str2))
      If Not str1.Equals(str2) Then
         Console.WriteLine(str2)
         For Each ch In str2
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
         Next    
         Console.WriteLine()
      End If 
   End Sub
End Module
' The example displays the following output:
'       Ⓢ ⁵ ∞
'       24C8 0020 2075 0020 221E
'       Round-trip: False
'       * * *
'       002A 0020 002A 0020 002A

Nota

Si può anche implementare una classe di sostituzione per una codifica.You can also implement a replacement class for an encoding. Per altre informazioni, vedere la sezione Implementing a Custom Fallback Strategy .For more information, see the Implementing a Custom Fallback Strategy section.

Oltre a QUESTION MARK (U+003F), anche il carattere Unicode REPLACEMENT CHARACTER (U+FFFD) viene di solito usato come stringa di sostituzione, in particolare quando si decodificano sequenze di byte che non possono essere convertite in caratteri Unicode.In addition to QUESTION MARK (U+003F), the Unicode REPLACEMENT CHARACTER (U+FFFD) is commonly used as a replacement string, particularly when decoding byte sequences that cannot be successfully translated into Unicode characters. Tuttavia è possibile scegliere qualsiasi stringa di sostituzione, che potrà contenere più caratteri.However, you are free to choose any replacement string, and it can contain multiple characters.

Exception FallbackException Fallback

Invece di fornire un fallback con mapping più appropriato o una stringa di sostituzione, un codificatore può generare un'eccezione EncoderFallbackException se non può codificare un set di caratteri, mentre un decodificatore può generare un'eccezione DecoderFallbackException se non può decodificare una matrice di byte.Instead of providing a best-fit fallback or a replacement string, an encoder can throw an EncoderFallbackException if it is unable to encode a set of characters, and a decoder can throw a DecoderFallbackException if it is unable to decode a byte array. Per generare un'eccezione durante le operazioni di codifica e decodifica, si passa rispettivamente un oggetto EncoderExceptionFallback e un oggetto DecoderExceptionFallback al metodo Encoding.GetEncoding(String, EncoderFallback, DecoderFallback) .To throw an exception in encoding and decoding operations, you supply an EncoderExceptionFallback object and a DecoderExceptionFallback object, respectively, to the Encoding.GetEncoding(String, EncoderFallback, DecoderFallback) method. L'esempio seguente illustra il fallback di eccezione con la classe ASCIIEncoding .The following example illustrates exception fallback with the ASCIIEncoding class.

using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      Encoding enc = Encoding.GetEncoding("us-ascii", 
                                          new EncoderExceptionFallback(), 
                                          new DecoderExceptionFallback());
      
      string str1 = "\u24C8 \u2075 \u221E";
      Console.WriteLine(str1);
      foreach (var ch in str1)
         Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));

      Console.WriteLine("\n");

      // Encode the original string using the ASCII encoder.
      byte[] bytes = {};
      try {
         bytes = enc.GetBytes(str1);
         Console.Write("Encoded bytes: ");
         foreach (var byt in bytes)
            Console.Write("{0:X2} ", byt);

         Console.WriteLine();
      }
      catch (EncoderFallbackException e) {
         Console.Write("Exception: ");
         if (e.IsUnknownSurrogate())
            Console.WriteLine("Unable to encode surrogate pair 0x{0:X4} 0x{1:X3} at index {2}.", 
                              Convert.ToUInt16(e.CharUnknownHigh), 
                              Convert.ToUInt16(e.CharUnknownLow), 
                              e.Index);
         else
            Console.WriteLine("Unable to encode 0x{0:X4} at index {1}.", 
                              Convert.ToUInt16(e.CharUnknown), 
                              e.Index);
         return;
      }
      Console.WriteLine();

      // Decode the ASCII bytes.
      try {
         string str2 = enc.GetString(bytes);
         Console.WriteLine("Round-trip: {0}", str1.Equals(str2));
         if (! str1.Equals(str2)) {
            Console.WriteLine(str2);
            foreach (var ch in str2)
               Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));

            Console.WriteLine();
         } 
      }
      catch (DecoderFallbackException e) {
         Console.Write("Unable to decode byte(s) ");
         foreach (byte unknown in e.BytesUnknown)
            Console.Write("0x{0:X2} ");

         Console.WriteLine("at index {0}", e.Index);
      }
   }
}
// The example displays the following output:
//       Ⓢ ⁵ ∞
//       24C8 0020 2075 0020 221E
//       
//       Exception: Unable to encode 0x24C8 at index 0.
Imports System.Text

Module Example
   Public Sub Main()
      Dim enc As Encoding = Encoding.GetEncoding("us-ascii", 
                                                 New EncoderExceptionFallback(), 
                                                 New DecoderExceptionFallback())
      
      Dim str1 As String = String.Format("{0} {1} {2}", ChrW(&h24C8), ChrW(&h2075), ChrW(&h221E))
      Console.WriteLine(str1)
      For Each ch In str1
         Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
      Next    
      Console.WriteLine()
      Console.WriteLine() 

      ' Encode the original string using the ASCII encoder.
      Dim bytes() As Byte = {}
      Try
         bytes = enc.GetBytes(str1)
         Console.Write("Encoded bytes: ")
         For Each byt In bytes
            Console.Write("{0:X2} ", byt)
         Next
         Console.WriteLine()
      Catch e As EncoderFallbackException
         Console.Write("Exception: ")
         If e.IsUnknownSurrogate() Then
            Console.WriteLine("Unable to encode surrogate pair 0x{0:X4} 0x{1:X3} at index {2}.", 
                              Convert.ToUInt16(e.CharUnknownHigh), 
                              Convert.ToUInt16(e.CharUnknownLow), 
                              e.Index)
         Else
            Console.WriteLine("Unable to encode 0x{0:X4} at index {1}.", 
                              Convert.ToUInt16(e.CharUnknown), 
                              e.Index)
         End If                              
         Exit Sub
      End Try
      Console.WriteLine()

      ' Decode the ASCII bytes.
      Try
         Dim str2 As String = enc.GetString(bytes)
         Console.WriteLine("Round-trip: {0}", str1.Equals(str2))
         If Not str1.Equals(str2) Then
            Console.WriteLine(str2)
            For Each ch In str2
               Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
            Next    
            Console.WriteLine()
         End If 
      Catch e As DecoderFallbackException
         Console.Write("Unable to decode byte(s) ")
         For Each unknown As Byte In e.BytesUnknown
            Console.Write("0x{0:X2} ")
         Next
         Console.WriteLine("at index {0}", e.Index)
      End Try
   End Sub
End Module
' The example displays the following output:
'       Ⓢ ⁵ ∞
'       24C8 0020 2075 0020 221E
'       
'       Exception: Unable to encode 0x24C8 at index 0.

Nota

Si può anche implementare un gestore di eccezioni personalizzato per un'operazione di codifica.You can also implement a custom exception handler for an encoding operation. Per altre informazioni, vedere la sezione Implementing a Custom Fallback Strategy .For more information, see the Implementing a Custom Fallback Strategy section.

Gli oggetti EncoderFallbackException e DecoderFallbackException forniscono le seguenti informazioni sulla condizione che ha causato l'eccezione:The EncoderFallbackException and DecoderFallbackException objects provide the following information about the condition that caused the exception:

Anche se gli oggetti EncoderFallbackException e DecoderFallbackException forniscono informazioni diagnostiche adeguate sull'eccezione, tuttavia non forniscono accesso al buffer di codifica o di decodifica.Although the EncoderFallbackException and DecoderFallbackException objects provide adequate diagnostic information about the exception, they do not provide access to the encoding or decoding buffer. Quindi non consentono di sostituire o correggere i dati non validi nel metodo di codifica o di decodifica.Therefore, they do not allow invalid data to be replaced or corrected within the encoding or decoding method.

Implementing a Custom Fallback StrategyImplementing a Custom Fallback Strategy

Oltre al mapping più appropriato che viene implementato internamente dalle tabelle codici, .NET include le classi seguenti per implementare una strategia di fallback:In addition to the best-fit mapping that is implemented internally by code pages, .NET includes the following classes for implementing a fallback strategy:

Inoltre, è possibile implementare una soluzione personalizzata che usa il fallback con mapping più appropriato, il fallback di sostituzione o il fallback di eccezione, attenendosi alla procedura seguente:In addition, you can implement a custom solution that uses best-fit fallback, replacement fallback, or exception fallback, by following these steps:

  1. Derivare una classe da EncoderFallback per le operazioni di codifica e da DecoderFallback per le operazioni di decodifica.Derive a class from EncoderFallback for encoding operations, and from DecoderFallback for decoding operations.

  2. Derivare una classe da EncoderFallbackBuffer per le operazioni di codifica e da DecoderFallbackBuffer per le operazioni di decodifica.Derive a class from EncoderFallbackBuffer for encoding operations, and from DecoderFallbackBuffer for decoding operations.

  3. Per il fallback di eccezione, se le classi predefinite EncoderFallbackException e DecoderFallbackException non rispondono alle esigenze specifiche, derivare una classe da un oggetto eccezione, ad esempio Exception o ArgumentException.For exception fallback, if the predefined EncoderFallbackException and DecoderFallbackException classes do not meet your needs, derive a class from an exception object such as Exception or ArgumentException.

Derivazione da EncoderFallback o DecoderFallbackDeriving from EncoderFallback or DecoderFallback

Per implementare una soluzione di fallback personalizzata, è necessario creare una classe che eredita da EncoderFallback per le operazioni di codifica e da DecoderFallback per le operazioni di decodifica.To implement a custom fallback solution, you must create a class that inherits from EncoderFallback for encoding operations, and from DecoderFallback for decoding operations. Le istanze di queste classi vengono passate al metodo Encoding.GetEncoding(String, EncoderFallback, DecoderFallback) e fungono da intermediario tra la classe Encoding e l'implementazione del fallback.Instances of these classes are passed to the Encoding.GetEncoding(String, EncoderFallback, DecoderFallback) method and serve as the intermediary between the encoding class and the fallback implementation.

Quando si crea una soluzione di fallback personalizzata per un codificatore o un decodificatore, è necessario implementare i membri seguenti:When you create a custom fallback solution for an encoder or decoder, you must implement the following members:

Derivazione da EncoderFallbackBuffer o DecoderFallbackBufferDeriving from EncoderFallbackBuffer or DecoderFallbackBuffer

Per implementare una soluzione di fallback personalizzata, è necessario creare anche una classe che eredita da EncoderFallbackBuffer per le operazioni di codifica e da DecoderFallbackBuffer per le operazioni di decodifica.To implement a custom fallback solution, you must also create a class that inherits from EncoderFallbackBuffer for encoding operations, and from DecoderFallbackBuffer for decoding operations. Le istanze di queste classi vengono restituite dal metodo CreateFallbackBuffer delle classi EncoderFallback e DecoderFallback .Instances of these classes are returned by the CreateFallbackBuffer method of the EncoderFallback and DecoderFallback classes. Il metodo EncoderFallback.CreateFallbackBuffer viene chiamato dal codificatore quando rileva il primo carattere che non può codificare, mentre il metodo DecoderFallback.CreateFallbackBuffer viene chiamato dal decodificatore quando rileva uno o più byte che non può decodificare.The EncoderFallback.CreateFallbackBuffer method is called by the encoder when it encounters the first character that it is not able to encode, and the DecoderFallback.CreateFallbackBuffer method is called by the decoder when it encounters one or more bytes that it is not able to decode. Le classi EncoderFallbackBuffer e DecoderFallbackBuffer forniscono l'implementazione del fallback.The EncoderFallbackBuffer and DecoderFallbackBuffer classes provide the fallback implementation. Ogni istanza rappresenta un buffer contenente i caratteri di fallback che sostituiranno il carattere che non può essere codificato o la sequenza di byte che non può essere decodificata.Each instance represents a buffer that contains the fallback characters that will replace the character that cannot be encoded or the byte sequence that cannot be decoded.

Quando si crea una soluzione di fallback personalizzata per un codificatore o un decodificatore, è necessario implementare i membri seguenti:When you create a custom fallback solution for an encoder or decoder, you must implement the following members:

Se l'implementazione del fallback è un fallback con mapping più appropriato o un fallback di sostituzione, le classi derivate da EncoderFallbackBuffer e DecoderFallbackBuffer gestisco anche due campi di istanza privati: il numero esatto di caratteri nel buffer e l'indice del carattere successivo nel buffer da restituire.If the fallback implementation is a best-fit fallback or a replacement fallback, the classes derived from EncoderFallbackBuffer and DecoderFallbackBuffer also maintain two private instance fields: the exact number of characters in the buffer; and the index of the next character in the buffer to return.

Esempio di EncoderFallbackAn EncoderFallback Example

In un esempio precedente è stato usato il fallback di sostituzione per sostituire con un asterisco (*) i caratteri Unicode non corrispondenti a caratteri ASCII.An earlier example used replacement fallback to replace Unicode characters that did not correspond to ASCII characters with an asterisk (*). L'esempio seguente usa un'implementazione del fallback con mapping più appropriato personalizzato invece di fornire un mapping migliore dei caratteri non ASCII.The following example uses a custom best-fit fallback implementation instead to provide a better mapping of non-ASCII characters.

Il codice seguente definisce una classe denominata CustomMapper che deriva da EncoderFallback per gestire il mapping più appropriato dei caratteri non ASCII.The following code defines a class named CustomMapper that is derived from EncoderFallback to handle the best-fit mapping of non-ASCII characters. Il metodo CreateFallbackBuffer restituisce un oggetto CustomMapperFallbackBuffer oggetto che fornisce l'implementazione di EncoderFallbackBuffer .Its CreateFallbackBuffer method returns a CustomMapperFallbackBuffer object, which provides the EncoderFallbackBuffer implementation. La classe CustomMapper usa un oggetto Dictionary<TKey,TValue> per archiviare i mapping dei caratteri Unicode non supportati (valore chiave) e i corrispondenti caratteri a 8 bit (archiviati in due byte consecutivi in un Integer a 64 bit).The CustomMapper class uses a Dictionary<TKey,TValue> object to store the mappings of unsupported Unicode characters (the key value) and their corresponding 8-bit characters (which are stored in two consecutive bytes in a 64-bit integer). Per rendere questo mapping disponibile al buffer di fallback, l'istanza di CustomMapper viene passata come parametro al costruttore di classe CustomMapperFallbackBuffer .To make this mapping available to the fallback buffer, the CustomMapper instance is passed as a parameter to the CustomMapperFallbackBuffer class constructor. Poiché il mapping di più lungo è la stringa "INF" per il carattere Unicode U+221E, la proprietà MaxCharCount restituisce 3.Because the longest mapping is the string "INF" for the Unicode character U+221E, the MaxCharCount property returns 3.

public class CustomMapper : EncoderFallback
{
   public string DefaultString;
   internal Dictionary<ushort, ulong> mapping;

   public CustomMapper() : this("*")
   {   
   }
   
   public CustomMapper(string defaultString)
   {
      this.DefaultString = defaultString;

      // Create table of mappings
      mapping = new Dictionary<ushort, ulong>();
      mapping.Add(0x24C8, 0x53);
      mapping.Add(0x2075, 0x35);
      mapping.Add(0x221E, 0x49004E0046);
   }

   public override EncoderFallbackBuffer CreateFallbackBuffer()
   {
      return new CustomMapperFallbackBuffer(this);
   }

   public override int MaxCharCount
   {
      get { return 3; }
   } 
}
Public Class CustomMapper : Inherits EncoderFallback
   Public DefaultString As String
   Friend mapping As Dictionary(Of UShort, ULong)

   Public Sub New()
      Me.New("?")
   End Sub

   Public Sub New(ByVal defaultString As String)
      Me.DefaultString = defaultString

      ' Create table of mappings
      mapping = New Dictionary(Of UShort, ULong)
      mapping.Add(&H24C8, &H53)
      mapping.Add(&H2075, &H35)
      mapping.Add(&H221E, &H49004E0046)
   End Sub

   Public Overrides Function CreateFallbackBuffer() As System.Text.EncoderFallbackBuffer
      Return New CustomMapperFallbackBuffer(Me)
   End Function

   Public Overrides ReadOnly Property MaxCharCount As Integer
      Get
         Return 3
      End Get
   End Property
End Class

Il codice seguente definisce la classe CustomMapperFallbackBuffer , derivata da EncoderFallbackBuffer.The following code defines the CustomMapperFallbackBuffer class, which is derived from EncoderFallbackBuffer. Il dizionario contenente i mapping più appropriati e definito nell'istanza di CustomMapper è disponibile nel costruttore di classe.The dictionary that contains best-fit mappings and that is defined in the CustomMapper instance is available from its class constructor. Il metodo Fallback restituisce true se uno dei caratteri Unicode che il codificatore ASCII non può codificare è definito nel dizionario dei mapping. In caso contrario, restituisce false.Its Fallback method returns true if any of the Unicode characters that the ASCII encoder cannot encode are defined in the mapping dictionary; otherwise, it returns false. Per ogni fallback, la variabile privata count indica il numero di caratteri ancora da restituire e la variabile privata index indica la posizione nel buffer della stringa, charsToReturn, del carattere successivo da restituire.For each fallback, the private count variable indicates the number of characters that remain to be returned, and the private index variable indicates the position in the string buffer, charsToReturn, of the next character to return.

public class CustomMapperFallbackBuffer : EncoderFallbackBuffer
{
   int count = -1;                   // Number of characters to return
   int index = -1;                   // Index of character to return
   CustomMapper fb; 
   string charsToReturn; 

   public CustomMapperFallbackBuffer(CustomMapper fallback)
   {
      this.fb = fallback;
   }

   public override bool Fallback(char charUnknownHigh, char charUnknownLow, int index)
   {
      // Do not try to map surrogates to ASCII.
      return false;
   }

   public override bool Fallback(char charUnknown, int index)
   {
      // Return false if there are already characters to map.
      if (count >= 1) return false;

      // Determine number of characters to return.
      charsToReturn = String.Empty;

      ushort key = Convert.ToUInt16(charUnknown);
      if (fb.mapping.ContainsKey(key)) {
         byte[] bytes = BitConverter.GetBytes(fb.mapping[key]);
         int ctr = 0;
         foreach (var byt in bytes) {
            if (byt > 0) {
               ctr++;
               charsToReturn += (char) byt;
            }
         }
         count = ctr;
      }
      else {
         // Return default.
         charsToReturn = fb.DefaultString;
         count = 1;
      }
      this.index = charsToReturn.Length - 1;

      return true;
   }

   public override char GetNextChar()
   {
      // We'll return a character if possible, so subtract from the count of chars to return.
      count--;
      // If count is less than zero, we've returned all characters.
      if (count < 0) 
         return '\u0000';

      this.index--;
      return charsToReturn[this.index + 1];
   }

   public override bool MovePrevious()
   {
      // Original: if count >= -1 and pos >= 0
      if (count >= -1) {
         count++;
         return true;
      }
      else {
         return false;
      }
   }

   public override int Remaining 
   {
      get { return count < 0 ? 0 : count; }
   }

   public override void Reset()
   {
      count = -1;
      index = -1;
   }
}
Public Class CustomMapperFallbackBuffer : Inherits EncoderFallbackBuffer

   Dim count As Integer = -1        ' Number of characters to return
   Dim index As Integer = -1        ' Index of character to return
   Dim fb As CustomMapper
   Dim charsToReturn As String

   Public Sub New(ByVal fallback As CustomMapper)
      MyBase.New()
      Me.fb = fallback
   End Sub

   Public Overloads Overrides Function Fallback(ByVal charUnknownHigh As Char, ByVal charUnknownLow As Char, ByVal index As Integer) As Boolean
      ' Do not try to map surrogates to ASCII.
      Return False
   End Function

   Public Overloads Overrides Function Fallback(ByVal charUnknown As Char, ByVal index As Integer) As Boolean
      ' Return false if there are already characters to map.
      If count >= 1 Then Return False

      ' Determine number of characters to return.
      charsToReturn = String.Empty

      Dim key As UShort = Convert.ToUInt16(charUnknown)
      If fb.mapping.ContainsKey(key) Then
         Dim bytes() As Byte = BitConverter.GetBytes(fb.mapping.Item(key))
         Dim ctr As Integer
         For Each byt In bytes
            If byt > 0 Then
               ctr += 1
               charsToReturn += Chr(byt)
            End If
         Next
         count = ctr
      Else
         ' Return default.
         charsToReturn = fb.DefaultString
         count = 1
      End If
      Me.index = charsToReturn.Length - 1

      Return True
   End Function

   Public Overrides Function GetNextChar() As Char
      ' We'll return a character if possible, so subtract from the count of chars to return.
      count -= 1
      ' If count is less than zero, we've returned all characters.
      If count < 0 Then Return ChrW(0)

      Me.index -= 1
      Return charsToReturn(Me.index + 1)
   End Function

   Public Overrides Function MovePrevious() As Boolean
      ' Original: if count >= -1 and pos >= 0
      If count >= -1 Then
         count += 1
         Return True
      Else
         Return False
      End If
   End Function

   Public Overrides ReadOnly Property Remaining As Integer
      Get
         Return If(count < 0, 0, count)
      End Get
   End Property

   Public Overrides Sub Reset()
      count = -1
      index = -1
   End Sub
End Class

Il codice seguente crea quindi un'istanza dell'oggetto CustomMapper e ne passa un'istanza al metodo Encoding.GetEncoding(String, EncoderFallback, DecoderFallback) .The following code then instantiates the CustomMapper object and passes an instance of it to the Encoding.GetEncoding(String, EncoderFallback, DecoderFallback) method. L'output indica che l'implementazione del fallback con mapping più appropriato gestisce correttamente i tre caratteri non ASCII nella stringa originale.The output indicates that the best-fit fallback implementation successfully handles the three non-ASCII characters in the original string.

using System;
using System.Collections.Generic;
using System.Text;

class Program
{
   static void Main()
   {
      Encoding enc = Encoding.GetEncoding("us-ascii", new CustomMapper(), new DecoderExceptionFallback());

      string str1 = "\u24C8 \u2075 \u221E";
      Console.WriteLine(str1);
      for (int ctr = 0; ctr <= str1.Length - 1; ctr++) {
         Console.Write("{0} ", Convert.ToUInt16(str1[ctr]).ToString("X4"));
         if (ctr == str1.Length - 1) 
            Console.WriteLine();
      }
      Console.WriteLine();

      // Encode the original string using the ASCII encoder.
      byte[] bytes = enc.GetBytes(str1);
      Console.Write("Encoded bytes: ");
      foreach (var byt in bytes)
         Console.Write("{0:X2} ", byt);

      Console.WriteLine("\n");

      // Decode the ASCII bytes.
      string str2 = enc.GetString(bytes);
      Console.WriteLine("Round-trip: {0}", str1.Equals(str2));
      if (! str1.Equals(str2)) {
         Console.WriteLine(str2);
         foreach (var ch in str2)
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));

         Console.WriteLine();
      }
   }
}
Imports System.Text
Imports System.Collections.Generic

Module Module1

   Sub Main()
      Dim enc As Encoding = Encoding.GetEncoding("us-ascii", New CustomMapper(), New DecoderExceptionFallback())

      Dim str1 As String = String.Format("{0} {1} {2}", ChrW(&H24C8), ChrW(&H2075), ChrW(&H221E))
      Console.WriteLine(str1)
      For ctr As Integer = 0 To str1.Length - 1
         Console.Write("{0} ", Convert.ToUInt16(str1(ctr)).ToString("X4"))
         If ctr = str1.Length - 1 Then Console.WriteLine()
      Next
      Console.WriteLine()

      ' Encode the original string using the ASCII encoder.
      Dim bytes() As Byte = enc.GetBytes(str1)
      Console.Write("Encoded bytes: ")
      For Each byt In bytes
         Console.Write("{0:X2} ", byt)
      Next
      Console.WriteLine()
      Console.WriteLine()

      ' Decode the ASCII bytes.
      Dim str2 As String = enc.GetString(bytes)
      Console.WriteLine("Round-trip: {0}", str1.Equals(str2))
      If Not str1.Equals(str2) Then
         Console.WriteLine(str2)
         For Each ch In str2
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
         Next
         Console.WriteLine()
      End If
   End Sub
End Module

Vedere ancheSee also