Questo articolo è stato tradotto automaticamente. Per visualizzare l'articolo in inglese, selezionare la casella di controllo Inglese. È possibile anche visualizzare il testo inglese in una finestra popup posizionando il puntatore del mouse sopra il testo.
Traduzione
Inglese

Interfaccia ICustomFormatter

 

Data di pubblicazione: ottobre 2016

Definisce un metodo che supporta la formattazione personalizzata del valore di un oggetto.

Spazio dei nomi:   System
Assembly:  mscorlib (in mscorlib.dll)

[ComVisibleAttribute(true)]
public interface ICustomFormatter

NomeDescrizione
System_CAPS_pubmethodFormat(String, Object, IFormatProvider)

Converte il valore di un oggetto specificato in una rappresentazione di stringa equivalente usando il formato e le informazioni di formattazione specifiche delle impostazioni cultura indicati.

Il ICustomFormatter interfaccia include un singolo metodo, ICustomFormatter.Format. Quando questa interfaccia viene implementata da un tipo di valore o riferimento, il Format metodo restituisce una rappresentazione di stringa con formattazione personalizzata del valore di un oggetto.

In genere, l'interfaccia ICustomFormatter viene implementata con l'interfaccia IFormatProvider per personalizzare il comportamento di due metodi di formattazione composta di stringhe di .NET Framework che includono un parametro IFormatProvider. In particolare, l'interfaccia ICustomFormatter è in grado di fornire una formattazione personalizzata del valore di un oggetto passato ai metodi String.Format(IFormatProvider, String, Object[]) e StringBuilder.AppendFormat(IFormatProvider, String, Object[]).

Fornisce una rappresentazione grafica del valore di un oggetto, è necessario procedere nel modo seguente:

  1. Definire una classe che implementa il ICustomFormatter interfaccia e il relativo membro singolo, il Format metodo.

  2. Definire una classe che implementa il IFormatProvider interfaccia e il relativo membro singolo, il GetFormat metodo. Il GetFormat metodo restituisce un'istanza di ICustomFormatter implementazione. Spesso, una singola classe implementa sia ICustomFormatter e IFormatProvider. In del tal caso, la classe GetFormat implementazione restituisce solo un'istanza di se stesso.

  3. Passare il IFormatProvider come implementazione di provider argomento del String.Format(IFormatProvider, String, Object[]) metodo o un metodo confrontabile.

Il metodo di .NET Framework utilizzerà quindi la formattazione personalizzata anziché il proprio.

Note per gli implementatori:

Common language runtime tenta di utilizzare il ICustomFormatter implementazione per ogni elemento di formato in una stringa di formato composita. Di conseguenza, è necessario prevedere che il ICustomFormatter verrà richiamata l'implementazione per fornire servizi di formattazione per gli oggetti o valori che non può per gestire. In questi casi, il Format metodo deve chiamare il metodo di formattazione appropriato per tale oggetto o un valore.

Esistono due tipi di ICustomFormatter implementazioni: intrinseche e l'estensione.

Le implementazioni intrinseche sono implementazioni che forniscono la formattazione personalizzata per un oggetto definito dall'applicazione. In questo caso, l'implementazione deve includere quanto segue:

  • Definizione delle stringhe di formato che definiscono la formattazione dell'oggetto. Stringhe di formato sono facoltative. In genere, una stringa di formato "G" o "g" definisce il formato generale (o utilizzato più di frequente). Tuttavia, si possono definire le stringhe di formato che si scelgono. Si possono anche decidere se sono con o senza maiuscole/minuscole.

  • Un test per assicurarsi che il tipo dell'oggetto passato per il Format metodo è il tipo definito dall'applicazione. In caso contrario, è necessario chiamare l'oggetto IFormattable implementazione, se presente, o il relativo ToString (metodo), in caso contrario. È consigliabile essere preparati gestire le eccezioni potrebbero generare queste chiamate al metodo.

  • Codice per gestire una stringa di formato null se l'implementazione supporta le stringhe di formato. L'approccio più comune consiste nel sostituire una stringa di formato null con l'identificatore di formato generale.

  • Codice per gestire le stringhe di formato che supporta l'implementazione.

  • Codice per gestire le stringhe di formato non supportato. L'approccio più comune consiste nel generare un FormatException, sebbene sia possibile fornire la formattazione predefinita.

Le implementazioni delle estensioni sono implementazioni che forniscono formattazione personalizzata per un tipo che dispone già di supporto per la formattazione. Ad esempio, è possibile definire un CustomerNumberFormatter che formatta un tipo integrale con trattini tra cifre specifiche. In questo caso, l'implementazione deve includere quanto segue:

  • Definizione delle stringhe di formato che estendono la formattazione dell'oggetto. Queste stringhe di formato sono necessarie, ma non devono creare conflitti con le stringhe di formato esistente del tipo. Ad esempio, se si estende la formattazione per il Int32 tipo, non è necessario implementare gli identificatori di formato "C", "D", "E", "F" e "G", tra gli altri.

  • Un test che il tipo dell'oggetto passato per il Format metodo è un tipo il cui l'estensione di formattazione è supportata. In caso contrario, chiamare l'oggetto IFormattable implementazione, se ne esiste uno, o senza parametri dell'oggetto ToString (metodo), in caso contrario. È consigliabile essere preparati gestire le eccezioni potrebbero generare queste chiamate al metodo.

  • Codice per gestire le stringhe di formato che supporta l'estensione.

  • Codice per gestire le stringhe di formato che non supporta l'estensione. Questi devono essere passati per il tipo IFormattable implementazione. È consigliabile essere preparati gestire le eccezioni potrebbero generare queste chiamate al metodo.

Nell'esempio seguente viene implementata ICustomFormatter per consentire la formattazione binaria, ottali ed esadecimali di valori integrali. In questo esempio, una singola classe, IBinaryFormatter, implementa sia ICustomFormatter e IFormatProvider. Il IFormatProvider.GetFormat metodo determina se il formatType parametro rappresenta un ICustomFormatter tipo. In caso affermativo, BinaryFormatter restituisce un'istanza di se stesso; in caso contrario, restituisce null. Il ICustomFormatter.Format implementazione determina se il parametro di formato è una delle tre stringhe di formato supportato ("B" per i dati binari, "O" per ottale e "H" per esadecimale) e formatta il arg parametro in modo appropriato. In caso contrario, se arg non null, chiama il arg del parametro IFormattable.ToString implementazione, se presente, o relativo senza parametri ToString (metodo), se non esiste. Se arg è null, il metodo restituisce String.Empty.

using System;
using System.Globalization;
using System.Numerics;

public class BinaryFormatter : IFormatProvider, ICustomFormatter
{
   // IFormatProvider.GetFormat implementation.
   public object GetFormat(Type formatType)
   {
      // Determine whether custom formatting object is requested.
      if (formatType == typeof(ICustomFormatter))
         return this;
      else
         return null;
   }   

   // Format number in binary (B), octal (O), or hexadecimal (H).
   public string Format(string format, object arg, IFormatProvider formatProvider)
   {
      // Handle format string.
      int baseNumber;
      // Handle null or empty format string, string with precision specifier.
      string thisFmt = String.Empty;
      // Extract first character of format string (precision specifiers
      // are not supported).
      if (! String.IsNullOrEmpty(format))
         thisFmt = format.Length > 1 ? format.Substring(0, 1) : format;


      // Get a byte array representing the numeric value.
      byte[] bytes;
      if (arg is sbyte)
      {
         string byteString = ((sbyte) arg).ToString("X2");
         bytes = new byte[1] { Byte.Parse(byteString, System.Globalization.NumberStyles.HexNumber ) };
      }
      else if (arg is byte) {
         bytes = new byte[1] { (byte) arg };
      }   
      else if (arg is short) {
         bytes = BitConverter.GetBytes((short) arg);
      }   
      else if (arg is int) {
         bytes = BitConverter.GetBytes((int) arg);
      }   
      else if (arg is long) {
         bytes = BitConverter.GetBytes((long) arg);
      }
      else if (arg is ushort) {
         bytes = BitConverter.GetBytes((ushort) arg);
      }
      else if (arg is uint) {
         bytes = BitConverter.GetBytes((uint) arg);
      }
      else if (arg is ulong) {
         bytes = BitConverter.GetBytes((ulong) arg);                  
      }
      else if (arg is BigInteger) {
         bytes = ((BigInteger) arg).ToByteArray();
      }
      else {
         try {
            return HandleOtherFormats(format, arg); 
         }
         catch (FormatException e) {
            throw new FormatException(String.Format("The format of '{0}' is invalid.", format), e);
         }
      }

      switch (thisFmt.ToUpper())
      {
         // Binary formatting.
         case "B":
            baseNumber = 2;
            break;        
         case "O":
            baseNumber = 8;
            break;
         case "H":
            baseNumber = 16;
            break;
         // Handle unsupported format strings.
         default:
         try {
            return HandleOtherFormats(format, arg); 
         }
         catch (FormatException e) {
            throw new FormatException(String.Format("The format of '{0}' is invalid.", format), e);
         }
      }

      // Return a formatted string.
      string numericString = String.Empty;
      for (int ctr = bytes.GetUpperBound(0); ctr >= bytes.GetLowerBound(0); ctr--)
      {
         string byteString = Convert.ToString(bytes[ctr], baseNumber);
         if (baseNumber == 2)
            byteString = new String('0', 8 - byteString.Length) + byteString;
         else if (baseNumber == 8)
            byteString = new String('0', 4 - byteString.Length) + byteString;
         // Base is 16.
         else     
            byteString = new String('0', 2 - byteString.Length) + byteString;

         numericString +=  byteString + " ";
      }
      return numericString.Trim();
   }

   private string HandleOtherFormats(string format, object arg)
   {
      if (arg is IFormattable) 
         return ((IFormattable)arg).ToString(format, CultureInfo.CurrentCulture);
      else if (arg != null)
         return arg.ToString();
      else
         return String.Empty;
   }
}

BinaryFormatter può quindi essere utilizzato per fornire una formattazione personalizzata passando un BinaryFormatter dell'oggetto come il provider parametro il Format (metodo), come illustrato nell'esempio seguente.

public class Example
{
   public static void Main()
   {
      Console.WindowWidth = 100;

      byte byteValue = 124;
      Console.WriteLine(String.Format(new BinaryFormatter(), 
                                      "{0} (binary: {0:B}) (hex: {0:H})", byteValue));

      int intValue = 23045;
      Console.WriteLine(String.Format(new BinaryFormatter(), 
                                      "{0} (binary: {0:B}) (hex: {0:H})", intValue));

      ulong ulngValue = 31906574882;
      Console.WriteLine(String.Format(new BinaryFormatter(), 
                                      "{0}\n   (binary: {0:B})\n   (hex: {0:H})", 
                                      ulngValue));

      BigInteger bigIntValue = BigInteger.Multiply(Int64.MaxValue, 2);
      Console.WriteLine(String.Format(new BinaryFormatter(), 
                                      "{0}\n   (binary: {0:B})\n   (hex: {0:H})", 
                                      bigIntValue));
   }
}
// The example displays the following output:
//    124 (binary: 01111100) (hex: 7c)
//    23045 (binary: 00000000 00000000 01011010 00000101) (hex: 00 00 5a 05)
//    31906574882
//       (binary: 00000000 00000000 00000000 00000111 01101101 11000111 10110010 00100010)
//       (hex: 00 00 00 07 6d c7 b2 22)
//    18446744073709551614
//       (binary: 00000000 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111110)
//       (hex: 00 ff ff ff ff ff ff ff fe)

Universal Windows Platform
Disponibile da 8
.NET Framework
Disponibile da 1.1
Libreria di classi portabile
Supportato in: piattaforme .NET portabili
Silverlight
Disponibile da 2.0
Windows Phone Silverlight
Disponibile da 7.0
Windows Phone
Disponibile da 8.1
Torna all'inizio
Mostra: