Ler en inglés

Compartir por


ICustomFormatter Interfaz

Definición

Define un método que admite formatos personalizados del valor de un objeto.

C#
public interface ICustomFormatter
C#
[System.Runtime.InteropServices.ComVisible(true)]
public interface ICustomFormatter
Derivado
Atributos

Ejemplos

En el ejemplo siguiente se implementa para permitir el formato binario, octal y hexadecimal de valores enteros ICustomFormatter . En este ejemplo, una sola clase, MyFormatter, implementa y ICustomFormatterIFormatProvider. Su IFormatProvider.GetFormat método determina si el formatType parámetro representa un ICustomFormatter tipo. Si lo hace, MyFormatter devuelve una instancia de sí misma; de lo contrario, devuelve null. Su ICustomFormatter.Format implementación determina si el parámetro de formato es una de las tres cadenas de formato admitidas ("B" para binary, "O" para octal y "H" para hexadecimal) y da formato al arg parámetro correctamente. De lo contrario, si arg no nulles , llama a la arg implementación del IFormattable.ToString parámetro, si existe, o a su método sin ToString parámetros, si no lo hace. Si el valor de arg es null, el método devuelve String.Empty.

C#
using System;
using System.Globalization;
using System.Numerics;

public class MyFormatter : 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;
    }
}

MyFormatter Después, se puede usar para proporcionar formato personalizado pasando un MyFormatter objeto como provider parámetro del Format método, como se muestra en el ejemplo siguiente.

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

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

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

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

        BigInteger bigIntValue = BigInteger.Multiply(Int64.MaxValue, 2);
        Console.WriteLine(String.Format(new MyFormatter(),
                                        "{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)

Comentarios

La ICustomFormatter interfaz incluye un único método, ICustomFormatter.Format. Cuando esta interfaz se implementa mediante un tipo de referencia o valor, el Format método devuelve una representación de cadena con formato personalizado del valor de un objeto.

Normalmente, la ICustomFormatter interfaz se implementa con la IFormatProvider interfaz para personalizar el comportamiento de dos métodos de formato de cadena compuesta de .NET Framework que incluyen un IFormatProvider parámetro. En concreto, la ICustomFormatter interfaz puede proporcionar formato personalizado del valor de un objeto pasado a los String.Format(IFormatProvider, String, Object[]) métodos y StringBuilder.AppendFormat(IFormatProvider, String, Object[]) .

Proporcionar una representación personalizada del valor de un objeto requiere que haga lo siguiente:

  1. Defina una clase que implemente la ICustomFormatter interfaz y su único miembro, el Format método .

  2. Defina una clase que implemente la IFormatProvider interfaz y su único miembro, el GetFormat método . El GetFormat método devuelve una instancia de la ICustomFormatter implementación. A menudo, una sola clase implementa y ICustomFormatterIFormatProvider. En ese caso, la implementación de la GetFormat clase simplemente devuelve una instancia de sí misma.

  3. Pase la IFormatProvider implementación como argumento provider del String.Format(IFormatProvider, String, Object[]) método o un método comparable.

A continuación, el método de biblioteca .NET usará el formato personalizado en lugar de su propio.

Notas a los implementadores

Common Language Runtime intenta usar la ICustomFormatter implementación de cada elemento de formato en una cadena de formato compuesto. Como resultado, debe esperar que se llame a la ICustomFormatter implementación para proporcionar servicios de formato a objetos o valores que no está diseñado para controlar. En estos casos, el Format(String, Object, IFormatProvider) método debe llamar al método de formato adecuado para ese objeto o valor.

Hay dos tipos de ICustomFormatter implementaciones: intrínsecas y extensiones.

Las implementaciones intrínsecas son implementaciones que proporcionan formato personalizado para un objeto definido por la aplicación. En este caso, la implementación debe incluir lo siguiente:

  • Definición de cadenas de formato que definen el formato del objeto. Las cadenas de formato son opcionales. Normalmente, una cadena de formato "G" o "g" define el formato general (o más usado). Sin embargo, es libre de definir las cadenas de formato que elija. También puede decidir si distingue mayúsculas de minúsculas o no distingue mayúsculas de minúsculas.

  • Prueba para asegurarse de que el tipo del objeto pasado al Format(String, Object, IFormatProvider) método es el tipo definido por la aplicación. Si no es así, debe llamar a la implementación del IFormattable objeto, si existe, o su ToString() método, si no lo hace. Debe estar preparado para controlar las excepciones que podrían producir estas llamadas de método.

  • Código para controlar una cadena de formato NULL, si la implementación admite cadenas de formato. El enfoque más común es reemplazar una cadena de formato NULL por el especificador de formato general.

  • Código para controlar las cadenas de formato que admita la implementación.

  • Código para controlar las cadenas de formato que no admite. El enfoque más común es iniciar un FormatException, aunque puede proporcionar formato predeterminado.

Las implementaciones de extensión son implementaciones que proporcionan formato personalizado para un tipo que ya tiene compatibilidad con el formato. Por ejemplo, podría definir un CustomerNumberFormatter que da formato a un tipo entero con guiones entre dígitos específicos. En este caso, la implementación debe incluir lo siguiente:

  • Definición de cadenas de formato que extienden el formato del objeto. Estas cadenas de formato son necesarias, pero no deben entrar en conflicto con las cadenas de formato existentes del tipo. Por ejemplo, si va a extender el formato para el Int32 tipo, no debe implementar los especificadores de formato "C", "D", "E", "F" y "G", entre otros.

  • Una prueba de que el tipo del objeto pasado al Format(String, Object, IFormatProvider) método es un tipo cuyo formato admite la extensión. Si no es así, llame a la implementación del IFormattable objeto, si existe, o al método sin ToString() parámetros del objeto, si no lo hace. Debe estar preparado para controlar las excepciones que podrían producir estas llamadas de método.

  • Código para controlar las cadenas de formato que admita la extensión.

  • Código para controlar las cadenas de formato que la extensión no admite. Estos deben pasarse a la implementación del IFormattable tipo. Debe estar preparado para controlar las excepciones que podrían producir estas llamadas de método.

Métodos

Format(String, Object, IFormatProvider)

Convierte el valor del objeto especificado en la representación de cadena equivalente usando el formato y la información de formato específica de la referencia cultural especificados.

Se aplica a

Produto Versións
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9, 10
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0

Consulte también