Compartir a través de


Formatos compuestos

La característica de formato compuesto de .NET toma una lista de objetos y una cadena de formato compuesto como entrada. Una cadena de formato compuesto consta de texto fijo mezclado con marcadores de posición indexados, denominados elementos de formato. Estos elementos de formato corresponden a los objetos de la lista. La operación de formato genera una cadena de resultado compuesta por el texto fijo original combinado con la representación de cadena de los objetos de la lista.

Importante

En lugar de usar cadenas de formato compuesto, puede usar cadenas interpoladas si el idioma y su versión que usa admiten. Una cadena interpolada contiene expresiones interpoladas. Cada expresión interpolada se resuelve con el valor de la expresión y se incluye en la cadena de resultado cuando se asigna la cadena. Para obtener más información, vea Interpolación de cadenas (Referencia de C#) y Cadenas interpoladas (Referencia de Visual Basic).

Los métodos siguientes admiten la característica de formato compuesto:

Cadena de formato compuesto

Una cadena de formato compuesto y una lista de objetos se usan como argumentos de métodos que admiten la característica de formato compuesto. Una cadena de formato compuesto consta de cero o más ejecuciones de texto fijo entremezclados con uno o varios elementos de formato. El texto fijo es cualquier cadena que elijas, y cada elemento de formato corresponde a un objeto o estructura encapsulada en la lista. La representación de cadena de cada objeto reemplaza el elemento de formato correspondiente.

Tenga en cuenta el fragmento de código siguiente Format :

string.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now);
String.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now)

El texto fijo es Name = y , hours = . Los elementos de formato son {0}, cuyo índice de 0 corresponde al objeto namey {1:hh}, cuyo índice de 1 corresponde al objeto DateTime.Now.

Sintaxis de elemento de formato

Cada elemento de formato presenta la siguiente sintaxis, formada por los siguientes componentes:

{index[,width][:formatString]}

Las llaves ({ y }) son necesarias.

Componente de índice

El componente obligatorio index , que también se denomina especificador de parámetros, es un número a partir de 0 que identifica un elemento correspondiente en la lista de objetos. Es decir, el elemento de formato cuyo especificador de parámetros es 0 formatea el primer objeto de la lista. El elemento de formato cuyo especificador de parámetro es 1 formatea el segundo objeto de la lista, y así sucesivamente. En el ejemplo siguiente se incluyen cuatro especificadores de parámetros, cero numerado a tres, para representar números primos inferiores a 10:

string primes = string.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                              2, 3, 5, 7);
Console.WriteLine(primes);

// The example displays the following output:
//      Four prime numbers: 2, 3, 5, 7
Dim primes As String = String.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                      2, 3, 5, 7)
Console.WriteLine(primes)

'The example displays the following output
'     Four prime numbers 2, 3, 5, 7

Varios elementos de formato pueden hacer referencia al mismo elemento de la lista de objetos especificando el mismo especificador de parámetros. Por ejemplo, puede dar formato al mismo valor numérico en formato hexadecimal, científico y numérico especificando una cadena de formato compuesto como , como "0x{0:X} {0:E} {0:N}"se muestra en el ejemplo siguiente:

string multiple = string.Format("0x{0:X} {0:E} {0:N}",
                                Int64.MaxValue);
Console.WriteLine(multiple);

// The example displays the following output:
//      0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
Dim multiple As String = String.Format("0x{0:X} {0:E} {0:N}",
                                       Int64.MaxValue)
Console.WriteLine(multiple)

'The example displays the following output
'     0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00

Cada elemento de formato puede hacer referencia a cualquier objeto de la lista. Por ejemplo, si hay tres objetos, puede dar formato al segundo, primero y tercer objeto especificando una cadena de formato compuesto como {1} {0} {2}. Se omite un objeto al que no hace referencia un elemento de formato. Se lanza un FormatException en tiempo de ejecución si un especificador de parámetros designa un elemento fuera de los límites de la lista de objetos.

Componente width

El componente opcional width es un entero con signo que indica el ancho de campo con formato preferido. Si el valor de width es menor que la longitud de la cadena con formato, width se omite y la longitud de la cadena con formato se usa como ancho de campo. Los datos con formato en el campo están alineados a la derecha si width son positivos y alineados a la izquierda si width son negativos. Si es necesario relleno, se usa espacio en blanco. La coma es necesaria si width se especifica.

En el ejemplo siguiente se definen dos matrices, una que contiene los nombres de los empleados y la otra que contiene las horas que han trabajado durante dos semanas. La cadena de formato compuesto alinea a la izquierda los nombres en un campo de 20 caracteres y alinea a la derecha las horas en un campo de 5 caracteres. La cadena de formato estándar "N1" da formato a las horas con un dígito fraccionario.

string[] names = { "Adam", "Bridgette", "Carla", "Daniel",
                   "Ebenezer", "Francine", "George" };
decimal[] hours = { 40, 6.667m, 40.39m, 82,
                    40.333m, 80, 16.75m };

Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours");

for (int counter = 0; counter < names.Length; counter++)
    Console.WriteLine("{0,-20} {1,5:N1}", names[counter], hours[counter]);

// The example displays the following output:
//      Name                 Hours
//      
//      Adam                  40.0
//      Bridgette              6.7
//      Carla                 40.4
//      Daniel                82.0
//      Ebenezer              40.3
//      Francine              80.0
//      George                16.8
Dim names As String() = {"Adam", "Bridgette", "Carla", "Daniel",
                         "Ebenezer", "Francine", "George"}

Dim hours As Decimal() = {40, 6.667D, 40.39D, 82,
                          40.333D, 80, 16.75D}

Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours")

For counter = 0 To names.Length - 1
    Console.WriteLine("{0,-20} {1,5:N1}", names(counter), hours(counter))
Next

'The example displays the following output
'     Name                 Hours
'     
'     Adam                  40.0
'     Bridgette              6.7
'     Carla                 40.4
'     Daniel                82.0
'     Ebenezer              40.3
'     Francine              80.0
'     George                16.8

Format String (componente)

El componente opcional formatString es una cadena de formato adecuada para el tipo de objeto al que se va a dar formato. Puede especificar:

  • Cadena de formato numérico estándar o personalizado si el objeto correspondiente es un valor numérico.
  • Cadena de formato de fecha y hora estándar o personalizada si el objeto correspondiente es un DateTime objeto .
  • Cadena de formato de enumeración si el objeto correspondiente es un valor de enumeración.

Si formatString no se especifica, se usa el especificador de formato general ("G") para un tipo numérico, de fecha y hora o de enumeración. Si se especifica formatString, son necesarios los dos puntos.

En la tabla siguiente se enumeran los tipos o categorías de tipos de la biblioteca de clases de .NET que admiten un conjunto predefinido de cadenas de formato y se proporcionan vínculos a los artículos que enumeran las cadenas de formato admitidas. El formato de cadena es un mecanismo extensible que permite definir nuevas cadenas de formato para todos los tipos existentes y definir un conjunto de cadenas de formato compatibles con un tipo definido por la aplicación.

Para obtener más información, consulte los artículos sobre la IFormattable interfaz y ICustomFormatter .

Tipo o categoría de tipo Vea
Tipos de fecha y hora (DateTime, DateTimeOffset) Cadenas de formato estándar de fecha y hora

Cadenas de formato personalizado de fecha y hora
Tipos de enumeración (todos los tipos derivados de System.Enum) Cadenas de formato de enumeración
Tipos numéricos (BigInteger, Byte, Decimal, Double, Int16, Int32, Int64, SByte, Single, UInt16, UInt32, UInt64) Cadenas con formato numérico estándar

Cadenas con formato numérico personalizado
Guid Guid.ToString(String)
TimeSpan Cadenas de formato TimeSpan estándar

Cadenas de formato TimeSpan personalizado

Llaves de escape

Las llaves de apertura y cierre se interpretan como inicio y finalización de un elemento de formato. Para que se muestre una llave de apertura o de cierre literal, debe utilizar una secuencia de escape. Especifique dos llaves de apertura ({{) en el texto fijo para mostrar una llave de apertura () o dos llaves de cierre ({}}) para mostrar una llave de cierre (}).

Las llaves de escape con un elemento de formato se analizan de forma diferente entre .NET y .NET Framework.

.RED

Las llaves se pueden escapar alrededor de un elemento de formato. Por ejemplo, considere el elemento {{{0:D}}}de formato , que está pensado para mostrar una llave de apertura, un valor numérico con formato de número decimal y una llave de cierre. El elemento de formato se interpreta de la siguiente manera:

  1. Las dos primeras llaves de apertura ({{) son llaves de escape y dan lugar a en una llave de apertura.
  2. Los tres caracteres siguientes ({0:) se interpretan como el inicio de un elemento de formato.
  3. El siguiente carácter (D) se interpreta como especificador de formato numérico estándar decimal.
  4. El siguiente corchete (}) se interpreta como el final del elemento de formato.
  5. Las dos llaves de cierre finales se escapan y producen una llave de cierre.
  6. El resultado final que se muestra es la cadena literal, {6324}.
int value = 6324;
string output = string.Format("{{{0:D}}}", value);

Console.WriteLine(output);
// The example displays the following output:
//       {6324}
Dim value As Integer = 6324
Dim output As String = String.Format("{{{0:D}}}", value)

Console.WriteLine(output)

'The example displays the following output
'      {6324}

.NET Framework

Las llaves de un elemento de formato se interpretan secuencialmente, en el orden en que se encuentran. No se admite la interpretación de llaves anidadas.

El modo de interpretar las llaves de escape puede dar lugar a resultados inesperados. Por ejemplo, considere el elemento {{{0:D}}}de formato , que está pensado para mostrar una llave de apertura, un valor numérico con formato de número decimal y una llave de cierre. Sin embargo, el elemento de formato se interpreta de la siguiente manera:

  1. Las dos primeras llaves de apertura ({{) son llaves de escape y dan lugar a en una llave de apertura.
  2. Los tres caracteres siguientes ({0:) se interpretan como el inicio de un elemento de formato.
  3. El siguiente carácter (D) se interpretaría como especificador de formato numérico estándar decimal, pero las dos llaves de escape siguientes (}}) producen una sola llave. Dado que la cadena resultante (D}) no es un especificador de formato numérico estándar, la cadena resultante se interpreta como una cadena de formato personalizado que significa mostrar la cadena D}literal .
  4. La última llave (}) se interpreta como el final del elemento de formato.
  5. El resultado final que se muestra es la cadena literal, {D}. No se muestra el valor numérico al que se va a dar formato.
int value = 6324;
string output = string.Format("{{{0:D}}}",
                              value);
Console.WriteLine(output);

// The example displays the following output:
//       {D}
Dim value As Integer = 6324
Dim output As String = String.Format("{{{0:D}}}",
                                     value)
Console.WriteLine(output)

'The example displays the following output:
'      {D}

Una forma de escribir código e impedir que las llaves de escape y los elementos de formato se malinterpreten consiste en dar formato a las llaves y elementos de formato por separado. Es decir, en la primera operación de formato, muestra una llave de apertura literal. En la siguiente operación, muestre el resultado del elemento de formato y, en la operación final, muestre una llave de cierre literal. En el ejemplo siguiente se muestra este enfoque:

int value = 6324;
string output = string.Format("{0}{1:D}{2}",
                             "{", value, "}");
Console.WriteLine(output);

// The example displays the following output:
//       {6324}
Dim value As Integer = 6324
Dim output As String = String.Format("{0}{1:D}{2}",
                                     "{", value, "}")
Console.WriteLine(output)

'The example displays the following output:
'      {6324}

Orden de procesamiento

Si la llamada al método de formato compuesto incluye un IFormatProvider argumento cuyo valor no es null, el tiempo de ejecución llama al método IFormatProvider.GetFormat para solicitar la implementación de ICustomFormatter. Si el método puede devolver una ICustomFormatter implementación, se almacena en caché durante la llamada al método de formato compuesto.

Cada valor de la lista de parámetros que corresponde a un elemento de formato se convierte en una cadena de la siguiente manera:

  1. Si el valor al que se va a dar formato es null, se devuelve una cadena String.Empty vacía.

  2. Si hay disponible una implementación de ICustomFormatter, el runtime llama al método Format. El tiempo de ejecución pasa el valor del elemento de formato formatString (o null si no está presente) al método. El tiempo de ejecución también pasa la implementación al método IFormatProvider. Si la llamada al ICustomFormatter.Format método devuelve null, la ejecución continúa con el paso siguiente. De lo contrario, se devuelve el resultado de la ICustomFormatter.Format llamada.

  3. Si el valor implementa la interfaz IFormattable, se llama al método ToString(String, IFormatProvider) de esta. Si uno de ellos está presente en el elemento de formato, el valor formatString se transfiere al método. De lo contrario, null no se pasa. El IFormatProvider argumento se determina de la manera siguiente:

  4. Se llama al método sin parámetros ToString del tipo, que reemplaza a Object.ToString() o hereda el comportamiento de su clase base. En este caso, se omite la cadena de formato especificada por el formatString componente en el elemento de formato, si está presente.

La alineación se aplica después de realizar los pasos anteriores.

Ejemplos de código

En el ejemplo siguiente se muestra una cadena creada con formato compuesto y otra creada mediante un método de objeto ToString. Ambos tipos de formato generan resultados equivalentes.

string formatString1 = string.Format("{0:dddd MMMM}", DateTime.Now);
string formatString2 = DateTime.Now.ToString("dddd MMMM");
Dim formatString1 As String = String.Format("{0:dddd MMMM}", DateTime.Now)
Dim formatString2 As String = DateTime.Now.ToString("dddd MMMM")

Suponiendo que el día actual es un jueves de mayo, el valor de ambas cadenas en el ejemplo anterior es Thursday May en la cultura inglesa de Estados Unidos.

Console.WriteLine expone la misma funcionalidad que String.Format. La única diferencia entre los dos métodos es que String.Format devuelve su resultado como una cadena, mientras Console.WriteLine escribe el resultado en el flujo de salida asociado al Console objeto . ** En el ejemplo siguiente se usa el Console.WriteLinemétodo para dar formato al valor de myNumber a un valor de moneda.

int myNumber = 100;
Console.WriteLine($"{myNumber:C}");

// The example displays the following output
// if en-US is the current culture:
//        $100.00
Dim myNumber As Integer = 100
Console.WriteLine("{0:C}", myNumber)

'The example displays the following output
'if en-US Is the current culture:
'       $100.00

En el ejemplo siguiente se muestra cómo dar formato a varios objetos, incluido el formato de un objeto de dos maneras diferentes:

string myName = "Fred";
Console.WriteLine(string.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                myName, DateTime.Now));

// Depending on the current time, the example displays output like the following:
//        Name = Fred, hours = 11, minutes = 30
Dim myName As String = "Fred"
Console.WriteLine(String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                myName, DateTime.Now))
'Depending on the current time, the example displays output Like the following:
'       Name = Fred, hours = 11, minutes = 30

En el ejemplo siguiente se muestra el uso del ancho en el formato. Los argumentos con formato se colocan entre caracteres de barra vertical (|) para resaltar la alineación resultante.

string firstName = "Fred";
string lastName = "Opals";
int myNumber = 100;

string formatFirstName = string.Format("First Name = |{0,10}|", firstName);
string formatLastName = string.Format("Last Name =  |{0,10}|", lastName);
string formatPrice = string.Format("Price =      |{0,10:C}|", myNumber);
Console.WriteLine(formatFirstName);
Console.WriteLine(formatLastName);
Console.WriteLine(formatPrice);
Console.WriteLine();

formatFirstName = string.Format("First Name = |{0,-10}|", firstName);
formatLastName = string.Format("Last Name =  |{0,-10}|", lastName);
formatPrice = string.Format("Price =      |{0,-10:C}|", myNumber);
Console.WriteLine(formatFirstName);
Console.WriteLine(formatLastName);
Console.WriteLine(formatPrice);

// The example displays the following output on a system whose current
// culture is en-US:
//     First Name = |      Fred|
//     Last Name =  |     Opals|
//     Price =      |   $100.00|
//
//     First Name = |Fred      |
//     Last Name =  |Opals     |
//     Price =      |$100.00   |
Dim firstName As String = "Fred"
Dim lastName As String = "Opals"
Dim myNumber As Integer = 100

Dim formatFirstName As String = String.Format("First Name = |{0,10}|", firstName)
Dim formatLastName As String = String.Format("Last Name =  |{0,10}|", lastName)
Dim formatPrice As String = String.Format("Price =      |{0,10:C}|", myNumber)
Console.WriteLine(formatFirstName)
Console.WriteLine(formatLastName)
Console.WriteLine(formatPrice)
Console.WriteLine()

formatFirstName = String.Format("First Name = |{0,-10}|", firstName)
formatLastName = String.Format("Last Name =  |{0,-10}|", lastName)
formatPrice = String.Format("Price =      |{0,-10:C}|", myNumber)
Console.WriteLine(formatFirstName)
Console.WriteLine(formatLastName)
Console.WriteLine(formatPrice)

'The example displays the following output on a system whose current
'culture Is en-US:
'    First Name = |      Fred|
'    Last Name =  |     Opals|
'    Price =      |   $100.00|
'
'    First Name = |Fred      |
'    Last Name =  |Opals     |
'    Price =      |$100.00   |

Consulte también