Formatos compuestosComposite Formatting

La característica de formato compuesto de .NET toma una lista de objetos y una cadena de formato compuesto como entrada.The .NET composite formatting feature takes a list of objects and a composite format string as input. Una cadena de formato compuesto está formada por texto fijo combinado con marcadores de posición indizados, que reciben el nombre de elementos de formato, y que se corresponden con los objetos de la lista.A composite format string consists of fixed text intermixed with indexed placeholders, called format items, that correspond to the objects in the list. 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.The formatting operation yields a result string that consists of the original fixed text intermixed with the string representation of the objects in the list.

Importante

En lugar de usar cadenas de formato compuesto, puede usar cadenas interpoladas si el idioma y la versión de idioma que está usando son compatibles con ellos.Instead of using composite format strings, you can use interpolated strings if the language and language version that you're using support them. Una cadena interpolada es una cadena que contiene expresiones interpoladas.An interpolated string is a string that contains interpolated expressions. 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.Each interpolated expression is resolved with the expression's value and included in the result string when the string is assigned. Para obtener más información, vea Interpolación de cadenas (Referencia de C#) e Interpolated strings (Visual Basic Reference) (Cadenas interpoladas [referencia de Visual Basic]).For more information, see String interpolation (C# Reference) and Interpolated strings (Visual Basic Reference).

La característica de formato compuesto se admite mediante métodos como los siguientes:The composite formatting feature is supported by methods such as the following:

Cadena de formato compuestoComposite Format String

Los métodos compatibles con la característica de formato compuesto utilizan como argumentos una cadena de formato compuesto y una lista de objetos.A composite format string and object list are used as arguments of methods that support the composite formatting feature. Una cadena de formato compuesto consta de cero o más ejecuciones de texto fijo combinadas con uno o varios elementos de formato.A composite format string consists of zero or more runs of fixed text intermixed with one or more format items. El texto fijo es cualquier cadena que elija y cada elemento de formato se corresponde con un objeto o estructura de conversión boxing de la lista.The fixed text is any string that you choose, and each format item corresponds to an object or boxed structure in the list. La característica de formato compuesto devuelve una nueva cadena de resultado donde cada elemento de formato se reemplaza por la representación de cadena del objeto correspondiente de la lista.The composite formatting feature returns a new result string where each format item is replaced by the string representation of the corresponding object in the list.

Observe el siguiente fragmento de código Format.Consider the following Format code fragment.

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

El texto fijo es "Name =" y ", hours =".The fixed text is "Name = " and ", hours = ". Los elementos de formato son "{0}", cuyo índice es 0, que corresponde al objeto name, y "{1:hh}", cuyo índice es 1, que corresponde al objeto DateTime.Now.The format items are "{0}", whose index is 0, which corresponds to the object name, and "{1:hh}", whose index is 1, which corresponds to the object DateTime.Now.

Sintaxis de elemento de formatoFormat Item Syntax

Cada elemento de formato presenta la siguiente sintaxis, formada por los siguientes componentes:Each format item takes the following form and consists of the following components:

{ index[,alignment][:formatString]}{ index[,alignment][:formatString]}

Las llaves ("{" y "}") son necesarias.The matching braces ("{" and "}") are required.

Index (Componente)Index Component

El componente index obligatorio, denominado también especificador de parámetros, es un número que empieza por 0 que identifica un elemento correspondiente de la lista de objetos.The mandatory index component, also called a parameter specifier, is a number starting from 0 that identifies a corresponding item in the list of objects. O sea, el elemento de formato cuyo especificador de parámetro es 0 da formato al primer objeto de la lista, el elemento de formato cuyo especificador de parámetro es 1 da formato al segundo objeto de la lista, etc.That is, the format item whose parameter specifier is 0 formats the first object in the list, the format item whose parameter specifier is 1 formats the second object in the list, and so on. En el ejemplo siguiente se incluyen cuatro especificadores de parámetros, numerados del cero al tres, para representar números primos menores que diez:The following example includes four parameter specifiers, numbered zero through three, to represent prime numbers less than ten:

string primes;
primes = String.Format("Prime numbers less than 10: {0}, {1}, {2}, {3}",
                       2, 3, 5, 7 );
Console.WriteLine(primes);
// The example displays the following output:
//      Prime numbers less than 10: 2, 3, 5, 7
Dim primes As String
primes = String.Format("Prime numbers less than 10: {0}, {1}, {2}, {3}",
                       2, 3, 5, 7 )
Console.WriteLine(primes)
' The example displays the following output:
'      Prime numbers less than 10: 2, 3, 5, 7

Los elementos de formato múltiple se pueden referir al mismo elemento de la lista de objetos mediante la especificación del mismo especificador de parámetro.Multiple format items can refer to the same element in the list of objects by specifying the same parameter specifier. Por ejemplo, se puede dar formato al mismo valor numérico en formato hexadecimal, científico y de número mediante la especificación de una cadena de formato compuesto como esta: "0x{0:X} {0:E} {0:N}", como se muestra en el ejemplo siguiente.For example, you can format the same numeric value in hexadecimal, scientific, and number format by specifying a composite format string such as : "0x{0:X} {0:E} {0:N}", as the following example shows.

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.Each format item can refer to any object in the list. Por ejemplo, si existen tres objetos, se puede dar formato al segundo, primero y tercer objeto mediante la especificación de una cadena de formato compuesto como esta: "{1} {0} {2}".For example, if there are three objects, you can format the second, first, and third object by specifying a composite format string like this: "{1} {0} {2}". Un objeto al que no hace referencia ningún elemento de formato se omite.An object that is not referenced by a format item is ignored. Se produce una excepción FormatException en tiempo de ejecución si un especificador de parámetro designa un elemento fuera de los límites de la lista de objetos.A FormatException is thrown at runtime if a parameter specifier designates an item outside the bounds of the list of objects.

Alignment (Componente)Alignment Component

El componente opcional alignment es un entero con signo que indica el ancho de campo con formato preferido.The optional alignment component is a signed integer indicating the preferred formatted field width. Si el valor de alignment es menor que la longitud de la cadena con formato, se omite alignment y se usa la longitud de la cadena con formato como el ancho de campo.If the value of alignment is less than the length of the formatted string, alignment is ignored and the length of the formatted string is used as the field width. Los datos con formato del campo están alineados a la derecha si alignment es positivo y a la izquierda si alignment es negativo.The formatted data in the field is right-aligned if alignment is positive and left-aligned if alignment is negative. Si hace falta relleno, se utiliza un espacio en blanco.If padding is necessary, white space is used. Si se especifica alignment, es necesaria la coma.The comma is required if alignment is specified.

El siguiente ejemplo define dos matrices, que contiene los nombres de empleados y otra contiene las horas que han trabajado en un período de dos semanas.The following example defines two arrays, one containing the names of employees and the other containing the hours they worked over a two-week period. 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.The composite format string left-aligns the names in a 20-character field, and right-aligns their hours in a 5-character field. Tenga en cuenta que la cadena de formato estándar "N1" también se usa para dar formato a las horas con un dígito fraccionario.Note that the "N1" standard format string is also used to format the hours with one fractional digit.

using System;

public class Example
{
   public static void Main()
   {
      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 ctr = 0; ctr < names.Length; ctr++)
         Console.WriteLine("{0,-20} {1,5:N1}", names[ctr], hours[ctr]);

   }
}
// 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
Module Example
   Public Sub Main()
      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}", "Name", "Hours")
      Console.WriteLine()
      For ctr As Integer = 0 To names.Length - 1
         Console.WriteLine("{0,-20} {1,5:N1}", names(ctr), hours(ctr))
      Next
   End Sub
End Module
' 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)Format String Component

El componente formatString opcional es una cadena de formato adecuada para el tipo de objeto al que se da formato.The optional formatString component is a format string that is appropriate for the type of object being formatted. Especifique una cadena de formato numérico estándar o personalizado si el objeto correspondiente es un valor numérico, una cadena de formato de fecha y hora estándar o personalizado si el objeto correspondiente es un objeto DateTime, o una cadena de formato de enumeración si el objeto correspondiente es un valor de enumeración.Specify a standard or custom numeric format string if the corresponding object is a numeric value, a standard or custom date and time format string if the corresponding object is a DateTime object, or an enumeration format string if the corresponding object is an enumeration value. Si no se especifica formatString, se usa el especificador de formato general ("G") para un tipo numérico, de fecha y hora o de enumeración.If formatString is not specified, the general ("G") format specifier for a numeric, date and time, or enumeration type is used. Si se especifica formatString, son necesarios los dos puntos.The colon is required if formatString is specified.

En la tabla siguiente se enumeran los tipos o las categorías de tipo de la biblioteca de clases de .NET Framework que admiten un conjunto predefinido de cadenas de formato, y se proporcionan vínculos a temas que muestran las cadenas de formato admitidas.The following table lists types or categories of types in the .NET Framework class library that support a predefined set of format strings, and provides links to the topics that list the supported format strings. Observe que la asignación de formato a cadenas es un mecanismo extensible que permite definir cadenas de formato nuevas para todos los tipos existentes, así como definir un conjunto de cadenas de formato admitidas por un tipo definido por la aplicación.Note that string formatting is an extensible mechanism that makes it possible to define new format strings for all existing types as well as to define a set of format strings supported by an application-defined type. Para obtener más información, consulte los temas sobre las interfaces IFormattable y ICustomFormatter.For more information, see the IFormattable and ICustomFormatter interface topics.

Tipo o categoría de tipoType or type category VeaSee
Tipos de fecha y hora (DateTime, DateTimeOffset)Date and time types (DateTime, DateTimeOffset) Standard Date and Time Format StringsStandard Date and Time Format Strings

Custom Date and Time Format StringsCustom Date and Time Format Strings
Tipos de enumeración (todos los tipos derivados de System.Enum)Enumeration types (all types derived from System.Enum) Enumeration Format StringsEnumeration Format Strings
Tipos numéricos (BigInteger, Byte, Decimal, Double, Int16, Int32, Int64, SByte, Single, UInt16, UInt32, UInt64)Numeric types (BigInteger, Byte, Decimal, Double, Int16, Int32, Int64, SByte, Single, UInt16, UInt32, UInt64) Standard Numeric Format StringsStandard Numeric Format Strings

Custom Numeric Format StringsCustom Numeric Format Strings
Guid Guid.ToString(String)
TimeSpan Cadenas de formato TimeSpan estándarStandard TimeSpan Format Strings

Cadenas de formato TimeSpan personalizadoCustom TimeSpan Format Strings

Llaves de escapeEscaping Braces

Las llaves de apertura y de cierre se interpretan como el inicio y el final de un elemento de formato.Opening and closing braces are interpreted as starting and ending a format item. Por lo tanto, debe utilizar una secuencia de escape para que se muestre una llave de apertura o de cierre literal.Consequently, you must use an escape sequence to display a literal opening brace or closing brace. Especifique dos llaves de apertura ("{{") en el texto fijo para que se muestre una llave de apertura ("{"), o dos llaves de cierre ("}}") para que se muestre una llave de cierre ("}").Specify two opening braces ("{{") in the fixed text to display one opening brace ("{"), or two closing braces ("}}") to display one closing brace ("}"). Las llaves de un elemento de formato se interpretan secuencialmente, en el orden en que se encuentran.Braces in a format item are interpreted sequentially in the order they are encountered. No se admite la interpretación de llaves anidadas.Interpreting nested braces is not supported.

El modo de interpretar las llaves de escape puede dar lugar a resultados inesperados.The way escaped braces are interpreted can lead to unexpected results. Tomemos como ejemplo el elemento de formato "{{{0:D}}}", cuyo propósito es mostrar una llave de apertura, un valor numérico con formato de número decimal y una llave de cierre;For example, consider the format item "{{{0:D}}}", which is intended to display an opening brace, a numeric value formatted as a decimal number, and a closing brace. pero que, en la práctica, se interpreta de la siguiente forma:However, the format item is actually interpreted in the following manner:

  1. Las dos primeras llaves de apertura ("{{") son llaves de escape y dan lugar a en una llave de apertura.The first two opening braces ("{{") are escaped and yield one opening brace.

  2. Los tres caracteres siguientes ("{0:") se interpretan como el inicio de un elemento de formato.The next three characters ("{0:") are interpreted as the start of a format item.

  3. El siguiente carácter ("D") se interpretaría como el especificador de formato numérico estándar decimal, pero las dos llaves de escape siguientes ("}}") dan lugar a una única llave.The next character ("D") would be interpreted as the Decimal standard numeric format specifier, but the next two escaped braces ("}}") yield a single brace. Como la cadena resultante ("D}") no es un especificador de formato numérico estándar, se interpreta como una cadena de formato personalizado que significa que debe mostrarse la cadena literal "D}".Because the resulting string ("D}") is not a standard numeric format specifier, the resulting string is interpreted as a custom format string that means display the literal string "D}".

  4. La última llave ("}") se interpreta como el final del elemento de formato.The last brace ("}") is interpreted as the end of the format item.

  5. Como resultado final, se muestra la cadena literal "{D}".The final result that is displayed is the literal string, "{D}". No se muestra el valor numérico al que se debía dar formato.The numeric value that was to be formatted is not displayed.

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.One way to write your code to avoid misinterpreting escaped braces and format items is to format the braces and format item separately. Es decir, en la primera operación de formato mostrar una llave de apertura literal, en la siguiente operación mostrar el resultado del elemento de formato y, por último, en la operación final mostrar una llave de cierre literal.That is, in the first format operation display a literal opening brace, in the next operation display the result of the format item, then in the final operation display a literal closing brace. En el ejemplo siguiente se muestra este enfoque.The following example illustrates this approach.

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 procesamientoProcessing Order

Si la llamada al método de formato compuesto incluye un argumento IFormatProvider cuyo valor no es null, el runtime llama al método IFormatProvider.GetFormat para solicitar una implementación de ICustomFormatter.If the call to the composite formatting method includes an IFormatProvider argument whose value is not null, the runtime calls its IFormatProvider.GetFormat method to request an ICustomFormatter implementation. Si el método es capaz de devolver una implementación de ICustomFormatter, se almacena en caché el tiempo que dure la llamada de método de formato compuesto.If the method is able to return an ICustomFormatter implementation, it's cached for the duration of the call of the composite formatting method.

Cada valor de la lista de parámetros que se corresponda con un elemento de formato se convierte en una cadena del siguiente modo:Each value in the parameter list that corresponds to a format item is converted to a string as follows:

  1. Si el valor al que se va a dar formato es null, se devuelve una cadena vacía String.Empty.If the value to be formatted is null, an empty string String.Empty is returned.

  2. Si hay disponible una implementación de ICustomFormatter, el runtime llama al método Format.If an ICustomFormatter implementation is available, the runtime calls its Format method. Pasa al método el valor formatString del elemento de formato, si hay alguno, o null si no lo hay, junto con la implementación de IFormatProvider.It passes the method the format item's formatString value, if one is present, or null if it's not, along with the IFormatProvider implementation. Si la llamada al método ICustomFormatter.Format devuelve null, la ejecución avanza al siguiente paso; en caso contrario, se devuelve el resultado de la llamada a ICustomFormatter.Format.If the call to the ICustomFormatter.Format method returns null, execution proceeds to the next step; otherwise, the result of the ICustomFormatter.Format call is returned.

  3. Si el valor implementa la interfaz IFormattable, se llama al método ToString(String, IFormatProvider) de esta.If the value implements the IFormattable interface, the interface's ToString(String, IFormatProvider) method is called. Se pasa al método el valor formatString, si hubiera uno presente en el elemento de formato, o null si no lo hubiera.The method is passed the formatString value, if one is present in the format item, or null if it's not. El argumento IFormatProvider se determina de la siguiente forma:The IFormatProvider argument is determined as follows:

  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.The type's parameterless ToString method, which either overrides Object.ToString() or inherits the behavior of its base class, is called. En este caso, se omite la cadena de formato especificada por el componente formatString en el elemento de formato, si estuviera presente.In this case, the format string specified by the formatString component in the format item, if it's present, is ignored.

La alineación se aplica después de que se hayan realizado los pasos anteriores.Alignment is applied after the preceding steps have been performed.

Ejemplos de códigoCode Examples

En el ejemplo siguiente se muestra una cadena creada mediante formato compuesto y otra creada mediante el método ToString de un objeto.The following example shows one string created using composite formatting and another created using an object's ToString method. Los dos tipos de formato producen resultados equivalentes.Both types of formatting produce equivalent results.

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") 

Si tomamos como día actual un jueves del mes de mayo, el valor de ambas cadenas del ejemplo anterior será Thursday May para la referencia cultural Inglés (Estados Unidos).Assuming that the current day is a Thursday in May, the value of both strings in the preceding example is Thursday May in the U.S. English culture.

Console.WriteLine expone la misma funcionalidad que String.Format.Console.WriteLine exposes the same functionality as String.Format. La única diferencia que existe entre estos dos métodos es que String.Format devuelve el resultado como una cadena, mientras que Console.WriteLine escribe el resultado en el flujo de salida asociado al objeto Console.The only difference between the two methods is that String.Format returns its result as a string, while Console.WriteLine writes the result to the output stream associated with the Console object. En el ejemplo siguiente se usa el método Console.WriteLine para dar formato al valor de MyInt como un valor de divisa.The following example uses the Console.WriteLine method to format the value of MyInt to a currency value.

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

En el siguiente ejemplo se muestra la aplicación de formato a objetos múltiples, incluida la aplicación de formato a un objeto de dos formas diferentes.The following example demonstrates formatting multiple objects, including formatting one object two different ways.

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 de la alineación en la aplicación de formato.The following example demonstrates the use of alignment in formatting. Los argumentos a los que se da formato se colocan entre caracteres verticales (|) para resaltar la alineación resultante.The arguments that are formatted are placed between vertical bar characters (|) to highlight the resulting alignment.

string myFName = "Fred";
string myLName = "Opals";
int myInt = 100;
string FormatFName = String.Format("First Name = |{0,10}|", myFName);
string FormatLName = String.Format("Last Name = |{0,10}|", myLName);
string FormatPrice = String.Format("Price = |{0,10:C}|", myInt); 
Console.WriteLine(FormatFName);
Console.WriteLine(FormatLName);
Console.WriteLine(FormatPrice);
Console.WriteLine();

FormatFName = String.Format("First Name = |{0,-10}|", myFName);
FormatLName = String.Format("Last Name = |{0,-10}|", myLName);
FormatPrice = String.Format("Price = |{0,-10:C}|", myInt);
Console.WriteLine(FormatFName);
Console.WriteLine(FormatLName);
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 myFName As String = "Fred"
   Dim myLName As String = "Opals"

   Dim myInt As Integer = 100
   Dim FormatFName As String = String.Format("First Name = |{0,10}|", myFName)
   Dim FormatLName As String = String.Format("Last Name = |{0,10}|", myLName)
   Dim FormatPrice As String = String.Format("Price = |{0,10:C}|", myInt)
   Console.WriteLine(FormatFName)
   Console.WriteLine(FormatLName)
   Console.WriteLine(FormatPrice)
   Console.WriteLine()
   
   FormatFName = String.Format("First Name = |{0,-10}|", myFName)
   FormatLName = String.Format("Last Name = |{0,-10}|", myLName)
   FormatPrice = String.Format("Price = |{0,-10:C}|", myInt)
   Console.WriteLine(FormatFName)
   Console.WriteLine(FormatLName)
   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   |

Vea tambiénSee also