Método System.String.Format
Este artigo fornece observações complementares à documentação de referência para essa API.
Importante
Em vez de chamar o método String.Format ou usar cadeias de caracteres de formato de composição, é possível usar cadeias de caracteres interpoladas quando a linguagem é compatível com eles. Uma cadeia de caracteres interpolada é uma cadeia de caracteres que contém expressões interpoladas. Cada expressão interpolada é resolvida com o valor da expressão e incluída na cadeia de caracteres resultante quando a cadeia de caracteres é atribuída. Para saber mais, consulte o tópico Interpolação de cadeia de caracteres (Referência do C#) ou Cadeias de caracteres interpoladas (Referência do Visual Basic).
Exemplos
Vários exemplos que chamam o Format método são intercalados ao longo deste artigo. Você também pode baixar um conjunto completo de String.Format
exemplos, que estão incluídos em um projeto .NET Core para C#.
A seguir estão alguns dos exemplos incluídos no artigo:
Criar uma cadeia de caracteres de formato
Inserir uma cadeia de caracteres
O item de formato
Formatar itens que tenham o mesmo índice
Controle de saída formatada
Formatação de controle
Espaçamento de controle
Alinhamento de controle
Controlar o número de dígitos integrais
Controlar o número de dígitos após o separador decimal
Incluir chaves literais na cadeia de caracteres de resultados
Tornar as cadeias de caracteres de formato sensíveis à cultura
Tornar as cadeias de caracteres de formato sensíveis à cultura
Personalizar a operação de formatação
Uma operação de formatação personalizada
Um provedor de interceptação e formatador de algarismos romanos
Introdução ao método String.Format
Use String.Format se você precisar inserir o valor de um objeto, variável ou expressão em outra cadeia de caracteres. Por exemplo, você pode inserir o valor de um Decimal valor em uma cadeia de caracteres para exibi-lo ao usuário como uma única cadeia de caracteres:
Decimal pricePerOunce = 17.36m;
String s = String.Format("The current price is {0} per ounce.",
pricePerOunce);
Console.WriteLine(s);
// Result: The current price is 17.36 per ounce.
let pricePerOunce = 17.36m
String.Format("The current price is {0} per ounce.", pricePerOunce)
|> printfn "%s"
// Result: The current price is 17.36 per ounce.
Dim pricePerOunce As Decimal = 17.36D
Dim s As String = String.Format("The current price is {0} per ounce.",
pricePerOunce)
' Result: The current price is 17.36 per ounce.
E você pode controlar a formatação desse valor:
Decimal pricePerOunce = 17.36m;
String s = String.Format("The current price is {0:C2} per ounce.",
pricePerOunce);
Console.WriteLine(s);
// Result if current culture is en-US:
// The current price is $17.36 per ounce.
let pricePerOunce = 17.36m
String.Format("The current price is {0:C2} per ounce.", pricePerOunce)
|> printfn "%s"
// Result if current culture is en-US:
// The current price is $17.36 per ounce.
Dim pricePerOunce As Decimal = 17.36D
Dim s As String = String.Format("The current price is {0:C2} per ounce.",
pricePerOunce)
' Result if current culture is en-US:
' The current price is $17.36 per ounce.
Além da formatação, você também pode controlar o alinhamento e o espaçamento.
Inserir uma cadeia de caracteres
String.Format Começa com uma cadeia de caracteres de formato, seguida por um ou mais objetos ou expressões que serão convertidos em cadeias de caracteres e inseridos em um local especificado na cadeia de caracteres de formato. Por exemplo:
decimal temp = 20.4m;
string s = String.Format("The temperature is {0}°C.", temp);
Console.WriteLine(s);
// Displays 'The temperature is 20.4°C.'
let temp = 20.4m
String.Format("The temperature is {0}°C.", temp)
|> printfn "%s"
// Displays 'The temperature is 20.4°C.'
Dim temp As Decimal = 20.4D
Dim s As String = String.Format("The temperature is {0}°C.", temp)
Console.WriteLine(s)
' Displays 'The temperature is 20.4°C.'
O {0}
na cadeia de caracteres de formato é um item de formato. 0
é o índice do objeto cujo valor de cadeia de caracteres será inserido nessa posição. (Os índices começam em 0.) Se o objeto a ser inserido não for uma cadeia de caracteres, seu ToString
método será chamado para convertê-lo em um antes de inseri-lo na cadeia de caracteres de resultado.
Aqui está outro exemplo que usa dois itens de formato e dois objetos na lista de objetos:
string s = String.Format("At {0}, the temperature is {1}°C.",
DateTime.Now, 20.4);
Console.WriteLine(s);
// Output similar to: 'At 4/10/2015 9:29:41 AM, the temperature is 20.4°C.'
String.Format("At {0}, the temperature is {1}°C.", DateTime.Now, 20.4)
|> printfn "%s"
// Output similar to: 'At 4/10/2015 9:29:41 AM, the temperature is 20.4°C.'
Dim s As String = String.Format("At {0}, the temperature is {1}°C.",
Date.Now, 20.4)
' Output similar to: 'At 4/10/2015 9:29:41 AM, the temperature is 20.4°C.'
Você pode ter quantos itens de formato e quantos objetos desejar na lista de objetos, desde que o índice de cada item de formato tenha um objeto correspondente na lista de objetos. Você também não precisa se preocupar com qual sobrecarga você chama; O compilador selecionará o apropriado para você.
Formatação de controle
Você pode seguir o índice em um item de formato com uma cadeia de caracteres de formato para controlar como um objeto é formatado. Por exemplo, {0:d}
aplica a cadeia de caracteres de formato "d" ao primeiro objeto na lista de objetos. Aqui está um exemplo com um único objeto e dois itens de formato:
string s = String.Format("It is now {0:d} at {0:t}", DateTime.Now);
Console.WriteLine(s);
// Output similar to: 'It is now 4/10/2015 at 10:04 AM'
String.Format("It is now {0:d} at {0:t}", DateTime.Now)
|> printfn "%s"
// Output similar to: 'It is now 4/10/2015 at 10:04 AM'
Dim s As String = String.Format("It is now {0:d} at {0:t}",
Date.Now)
' Output similar to: 'It is now 4/10/2015 at 10:04 AM'
Vários tipos oferecem suporte a cadeias de caracteres de formato, incluindo todos os tipos numéricos (cadeias de caracteres de formato padrão e personalizado), todas as datas e horas (cadeias de caracteres de formato padrão e personalizado) e intervalos de tempo (cadeias de caracteres de formato padrão e personalizado), todos os tipos de enumeração tipos de enumeração e GUIDs. Você também pode adicionar suporte para cadeias de caracteres de formato aos seus próprios tipos.
Espaçamento de controle
Você pode definir a largura da cadeia de caracteres inserida na cadeia de caracteres de resultado usando uma sintaxe como {0,12}
, que insere uma cadeia de caracteres de 12 caracteres. Nesse caso, a representação de cadeia de caracteres do primeiro objeto é alinhada à direita no campo de 12 caracteres. (No entanto, se a representação da cadeia de caracteres do primeiro objeto tiver mais de 12 caracteres, a largura do campo preferencial será ignorada e a cadeia de caracteres inteira será inserida na cadeia de caracteres de resultado.)
O exemplo a seguir define um campo de 6 caracteres para conter a cadeia de caracteres "Ano" e algumas cadeias de caracteres de ano, bem como um campo de 15 caracteres para conter a cadeia de caracteres "População" e alguns dados de população. Observe que os caracteres estão alinhados à direita no campo.
int[] years = { 2013, 2014, 2015 };
int[] population = { 1025632, 1105967, 1148203 };
var sb = new System.Text.StringBuilder();
sb.Append(String.Format("{0,6} {1,15}\n\n", "Year", "Population"));
for (int index = 0; index < years.Length; index++)
sb.Append(String.Format("{0,6} {1,15:N0}\n", years[index], population[index]));
Console.WriteLine(sb);
// Result:
// Year Population
//
// 2013 1,025,632
// 2014 1,105,967
// 2015 1,148,203
open System
open System.Text
let years = [| 2013; 2014; 2015 |]
let population = [| 1025632; 1105967; 1148203 |]
let sb = StringBuilder()
sb.Append(String.Format("{0,6} {1,15}\n\n", "Year", "Population")) |> ignore
for i = 0 to years.Length - 1 do
sb.Append(String.Format("{0,6} {1,15:N0}\n", years[i], population[i])) |> ignore
printfn $"{sb}"
// Result:
// Year Population
//
// 2013 1,025,632
// 2014 1,105,967
// 2015 1,148,203
Dim years() As Integer = {2013, 2014, 2015}
Dim population() As Integer = {1025632, 1105967, 1148203}
Dim sb As New StringBuilder()
sb.Append(String.Format("{0,6} {1,15}{2}{2}",
"Year", "Population", vbCrLf))
For index As Integer = 0 To years.Length - 1
sb.AppendFormat("{0,6} {1,15:N0}{2}",
years(index), population(index), vbCrLf)
Next
' Result:
' Year Population
'
' 2013 1,025,632
' 2014 1,105,967
' 2015 1,148,203
Alinhamento de controle
Por padrão, as cadeias de caracteres são alinhadas à direita dentro de seu campo se você especificar uma largura de campo. Para alinhar cadeias de caracteres à esquerda em um campo, você prefacia a largura do campo com um sinal negativo, como {0,-12}
para definir um campo alinhado à esquerda de 12 caracteres.
O exemplo a seguir é semelhante ao anterior, exceto que ele alinha à esquerda rótulos e dados.
int[] years = { 2013, 2014, 2015 };
int[] population = { 1025632, 1105967, 1148203 };
String s = String.Format("{0,-10} {1,-10}\n\n", "Year", "Population");
for (int index = 0; index < years.Length; index++)
s += String.Format("{0,-10} {1,-10:N0}\n",
years[index], population[index]);
Console.WriteLine($"\n{s}");
// Result:
// Year Population
//
// 2013 1,025,632
// 2014 1,105,967
// 2015 1,148,203
let years = [| 2013; 2014; 2015 |]
let population = [| 1025632; 1105967; 1148203 |]
let mutable s = String.Format("{0,-10} {1,-10}\n\n", "Year", "Population")
for i = 0 to years.Length - 1 do
s <- s + String.Format("{0,-10} {1,-10:N0}\n", years[i], population[i])
printfn $"\n{s}"
// Result:
// Year Population
//
// 2013 1,025,632
// 2014 1,105,967
// 2015 1,148,203
Dim years() As Integer = {2013, 2014, 2015}
Dim population() As Integer = {1025632, 1105967, 1148203}
Dim s As String = String.Format("{0,-10} {1,-10}{2}{2}",
"Year", "Population", vbCrLf)
For index As Integer = 0 To years.Length - 1
s += String.Format("{0,-10} {1,-10:N0}{2}",
years(index), population(index), vbCrLf)
Next
' Result:
' Year Population
'
' 2013 1,025,632
' 2014 1,105,967
' 2015 1,148,203
String.Format faz uso do recurso de formatação composta. Para obter mais informações, veja Formatação de composição.
Qual método devo chamar?
Para | Chamar |
---|---|
Formate um ou mais objetos usando as convenções da cultura atual. | Exceto para as sobrecargas que incluem um provider parâmetro, as sobrecargas restantes Format incluem um String parâmetro seguido por um ou mais parâmetros de objeto. Por isso, você não precisa determinar qual Format sobrecarga pretende chamar. Seu compilador de linguagem seleciona a sobrecarga apropriada entre as sobrecargas que não têm um provider parâmetro, com base em sua lista de argumentos. Por exemplo, se sua lista de argumentos tiver cinco argumentos, o compilador chamará o Format(String, Object[]) método. |
Formate um ou mais objetos usando as convenções de uma cultura específica. | Cada Format sobrecarga que começa com um provider parâmetro é seguida por um String parâmetro e um ou mais parâmetros de objeto. Por isso, você não precisa determinar qual sobrecarga específica Format pretende chamar. O compilador de linguagem seleciona a sobrecarga apropriada entre as sobrecargas que têm um provider parâmetro, com base na sua lista de argumentos. Por exemplo, se sua lista de argumentos tiver cinco argumentos, o compilador chamará o Format(IFormatProvider, String, Object[]) método. |
Execute uma operação de formatação personalizada com uma ICustomFormatter implementação ou uma IFormattable implementação. | Qualquer uma das quatro sobrecargas com um provider parâmetro. O compilador seleciona a sobrecarga apropriada entre as sobrecargas que têm um provider parâmetro, com base em sua lista de argumentos. |
O método Format resumido
Cada sobrecarga do Format método usa o recurso de formatação composta para incluir espaços reservados indexados baseados em zero, chamados itens de formato, em uma cadeia de caracteres de formato composto. Em tempo de execução, cada item de formato é substituído pela representação de cadeia de caracteres do argumento correspondente em uma lista de parâmetros. Se o valor do argumento for null
, o item de formato será substituído por String.Empty. Por exemplo, a chamada a seguir para o Format(String, Object, Object, Object) método inclui uma cadeia de caracteres de formato com três itens de formato, {0}, {1}e {2}, e uma lista de argumentos com três itens.
DateTime dat = new DateTime(2012, 1, 17, 9, 30, 0);
string city = "Chicago";
int temp = -16;
string output = String.Format("At {0} in {1}, the temperature was {2} degrees.",
dat, city, temp);
Console.WriteLine(output);
// The example displays output like the following:
// At 1/17/2012 9:30:00 AM in Chicago, the temperature was -16 degrees.
open System
let dat = DateTime(2012, 1, 17, 9, 30, 0)
let city = "Chicago"
let temp = -16
String.Format("At {0} in {1}, the temperature was {2} degrees.", dat, city, temp)
|> printfn "%s"
// The example displays output like the following:
// At 1/17/2012 9:30:00 AM in Chicago, the temperature was -16 degrees.
Dim dat As Date = #1/17/2012 9:30AM#
Dim city As String = "Chicago"
Dim temp As Integer = -16
Dim output As String = String.Format("At {0} in {1}, the temperature was {2} degrees.",
dat, city, temp)
Console.WriteLine(output)
' The example displays the following output:
' At 1/17/2012 9:30:00 AM in Chicago, the temperature was -16 degrees.
O item de formato
Um item de formato tem esta sintaxe:
{index[,alignment][:formatString]}
Os colchetes indicam elementos opcionais. As chaves de abertura e fechamento são obrigatórias. (Para incluir uma chave de abertura ou fechamento literal na cadeia de caracteres de formato, consulte o Seção Escapando chaves no artigo Formatação composta.)
Por exemplo, um item de formato para formatar um valor de moeda pode aparecer assim:
var value = String.Format("{0,-10:C}", 126347.89m);
Console.WriteLine(value);
open System
String.Format("{0,-10:C}", 126347.89m)
|> printfn "%s"
String.Format("{0,-10:C}", 126347.89D)
Um item de formato tem os seguintes elementos:
index
O índice baseado em zero do argumento cuja representação de cadeia de caracteres deve ser incluída nessa posição na cadeia de caracteres. Se esse argumento for null
, uma cadeia de caracteres vazia será incluída nessa posição na cadeia de caracteres.
alinhamento
Opcional. Um inteiro assinado que indica o comprimento total do campo no qual o argumento está inserido e se ele está alinhado à direita (um inteiro positivo) ou alinhado à esquerda (um inteiro negativo). Se você omitir o alinhamento, a representação de cadeia de caracteres do argumento correspondente será inserida em um campo sem espaços à esquerda ou à direita.
Se o valor do alinhamento for menor que o comprimento do argumento a ser inserido, o alinhamento será ignorado e o comprimento da representação da cadeia de caracteres do argumento será usado como a largura do campo.
formatString
Opcional. Uma cadeia de caracteres que especifica o formato da cadeia de caracteres de resultado do argumento correspondente. Se você omitir formatString, o método sem ToString
parâmetros do argumento correspondente será chamado para produzir sua representação de cadeia de caracteres. Se você especificar formatString, o argumento referenciado pelo item de formato deverá implementar a IFormattable interface. Os tipos que oferecem suporte a cadeias de caracteres de formato incluem:
Todos os tipos de integral e ponto flutuante. (Veja Cadeias de caracteres de formato numérico padrão e cadeias de caracteres de formato numérico personalizado.)
DateTime e DateTimeOffset. (Veja Cadeias de caracteres de formato de data e hora padrão e cadeias de caracteres de formato de data e hora personalizadas.)
Todos os tipos de enumeração. (Veja Sequências de Formato de Enumeração.)
valores TimeSpan. (Veja Cadeias de caracteres de formato TimeSpan padrão e cadeias de caracteres de formato TimeSpan personalizadas.)
GUIDs. (Veja o Guid.ToString(String) método.)
No entanto, observe que qualquer tipo personalizado pode implementar IFormattable ou estender a implementação de IFormattable um tipo existente.
O exemplo a seguir usa os alignment
argumentos e formatString
para produzir saída formatada.
// Create array of 5-tuples with population data for three U.S. cities, 1940-1950.
Tuple<string, DateTime, int, DateTime, int>[] cities =
{ Tuple.Create("Los Angeles", new DateTime(1940, 1, 1), 1504277,
new DateTime(1950, 1, 1), 1970358),
Tuple.Create("New York", new DateTime(1940, 1, 1), 7454995,
new DateTime(1950, 1, 1), 7891957),
Tuple.Create("Chicago", new DateTime(1940, 1, 1), 3396808,
new DateTime(1950, 1, 1), 3620962),
Tuple.Create("Detroit", new DateTime(1940, 1, 1), 1623452,
new DateTime(1950, 1, 1), 1849568) };
// Display header
var header = String.Format("{0,-12}{1,8}{2,12}{1,8}{2,12}{3,14}\n",
"City", "Year", "Population", "Change (%)");
Console.WriteLine(header);
foreach (var city in cities) {
var output = String.Format("{0,-12}{1,8:yyyy}{2,12:N0}{3,8:yyyy}{4,12:N0}{5,14:P1}",
city.Item1, city.Item2, city.Item3, city.Item4, city.Item5,
(city.Item5 - city.Item3)/ (double)city.Item3);
Console.WriteLine(output);
}
// The example displays the following output:
// City Year Population Year Population Change (%)
//
// Los Angeles 1940 1,504,277 1950 1,970,358 31.0 %
// New York 1940 7,454,995 1950 7,891,957 5.9 %
// Chicago 1940 3,396,808 1950 3,620,962 6.6 %
// Detroit 1940 1,623,452 1950 1,849,568 13.9 %
// Create a list of 5-tuples with population data for three U.S. cities, 1940-1950.
let cities =
[ "Los Angeles", DateTime(1940, 1, 1), 1504277, DateTime(1950, 1, 1), 1970358
"New York", DateTime(1940, 1, 1), 7454995, DateTime(1950, 1, 1), 7891957
"Chicago", DateTime(1940, 1, 1), 3396808, DateTime(1950, 1, 1), 3620962
"Detroit", DateTime(1940, 1, 1), 1623452, DateTime(1950, 1, 1), 1849568 ]
// Display header
String.Format("{0,-12}{1,8}{2,12}{1,8}{2,12}{3,14}\n", "City", "Year", "Population", "Change (%)")
|> printfn "%s"
for name, year1, pop1, year2, pop2 in cities do
String.Format("{0,-12}{1,8:yyyy}{2,12:N0}{3,8:yyyy}{4,12:N0}{5,14:P1}",
name, year1, pop1, year2, pop2,
double (pop2 - pop1) / double pop1)
|> printfn "%s"
// The example displays the following output:
// City Year Population Year Population Change (%)
//
// Los Angeles 1940 1,504,277 1950 1,970,358 31.0 %
// New York 1940 7,454,995 1950 7,891,957 5.9 %
// Chicago 1940 3,396,808 1950 3,620,962 6.6 %
// Detroit 1940 1,623,452 1950 1,849,568 13.9 %
Module Example3
Public Sub Main()
' Create array of 5-tuples with population data for three U.S. cities, 1940-1950.
Dim cities() =
{Tuple.Create("Los Angeles", #1/1/1940#, 1504277, #1/1/1950#, 1970358),
Tuple.Create("New York", #1/1/1940#, 7454995, #1/1/1950#, 7891957),
Tuple.Create("Chicago", #1/1/1940#, 3396808, #1/1/1950#, 3620962),
Tuple.Create("Detroit", #1/1/1940#, 1623452, #1/1/1950#, 1849568)}
' Display header
Dim header As String = String.Format("{0,-12}{1,8}{2,12}{1,8}{2,12}{3,14}",
"City", "Year", "Population", "Change (%)")
Console.WriteLine(header)
Console.WriteLine()
For Each city In cities
Dim output = String.Format("{0,-12}{1,8:yyyy}{2,12:N0}{3,8:yyyy}{4,12:N0}{5,14:P1}",
city.Item1, city.Item2, city.Item3, city.Item4, city.Item5,
(city.Item5 - city.Item3) / city.Item3)
Console.WriteLine(output)
Next
End Sub
End Module
' The example displays the following output:
' City Year Population Year Population Change (%)
'
' Los Angeles 1940 1,504,277 1950 1,970,358 31.0 %
' New York 1940 7,454,995 1950 7,891,957 5.9 %
' Chicago 1940 3,396,808 1950 3,620,962 6.6 %
' Detroit 1940 1,623,452 1950 1,849,568 13.9 %
Como os argumentos são formatados
Os itens de formato são processados sequencialmente a partir do início da cadeia de caracteres. Cada item de formato tem um índice que corresponde a um objeto na lista de argumentos do método. O Format método recupera o argumento e deriva sua representação de cadeia de caracteres da seguinte maneira:
Se o argumento for
null
, o método será insere na cadeia de String.Empty caracteres de resultado. Você não precisa se preocupar em lidar com argumentos nulos NullReferenceException .Se você chamar a Format(IFormatProvider, String, Object[]) sobrecarga e a
provider
implementação do IFormatProvider.GetFormat objeto retornar uma implementação não nula ICustomFormatter , o argumento será passado para seu ICustomFormatter.Format(String, Object, IFormatProvider) método. Se o item de formato incluir um argumento formatString , ele será passado como o primeiro argumento para o método. Se a ICustomFormatter implementação estiver disponível e produzir uma cadeia de caracteres não nula, essa cadeia de caracteres será retornada como a representação de cadeia de caracteres do argumento, caso contrário, a próxima etapa será executada.Se o argumento implementa a IFormattable interface, sua IFormattable.ToString implementação é chamada.
O método sem
ToString
parâmetros do argumento, que substitui ou herda de uma implementação de classe base, é chamado.
Para obter um exemplo que intercepta chamadas para o ICustomFormatter.Format método e permite que você veja quais informações o Format método passa para um método de formatação para cada item de formato em uma cadeia de caracteres de formato composto, consulte Exemplo: um provedor de interceptação e formatador de numeração romana.
Para obter mais informações, consulte Processando pedido.
Itens de formato que têm o mesmo índice
O Format método lança uma FormatException exceção se o índice de um item de índice for maior ou igual ao número de argumentos na lista de argumentos. No entanto, format
pode incluir mais itens de formato do que argumentos, desde que vários itens de formato tenham o mesmo índice. Na chamada para o Format(String, Object) método no exemplo a seguir, a lista de argumentos tem um único argumento, mas a cadeia de caracteres de formato inclui dois itens de formato: um exibe o valor decimal de um número e o outro exibe seu valor hexadecimal.
short[] values= { Int16.MinValue, -27, 0, 1042, Int16.MaxValue };
Console.WriteLine("{0,10} {1,10}\n", "Decimal", "Hex");
foreach (short value in values)
{
string formatString = String.Format("{0,10:G}: {0,10:X}", value);
Console.WriteLine(formatString);
}
// The example displays the following output:
// Decimal Hex
//
// -32768: 8000
// -27: FFE5
// 0: 0
// 1042: 412
// 32767: 7FFF
open System
let values= [| Int16.MinValue; -27s; 0s; 1042s; Int16.MaxValue |]
printfn "%10s %10s\n" "Decimal" "Hex"
for value in values do
String.Format("{0,10:G}: {0,10:X}", value)
|> printfn "%s"
// The example displays the following output:
// Decimal Hex
//
// -32768: 8000
// -27: FFE5
// 0: 0
// 1042: 412
// 32767: 7FFF
Module Example1
Public Sub Main()
Dim values() As Short = {Int16.MinValue, -27, 0, 1042, Int16.MaxValue}
Console.WriteLine("{0,10} {1,10}", "Decimal", "Hex")
Console.WriteLine()
For Each value As Short In values
Dim formatString As String = String.Format("{0,10:G}: {0,10:X}", value)
Console.WriteLine(formatString)
Next
End Sub
End Module
' The example displays the following output:
' Decimal Hex
'
' -32768: 8000
' -27: FFE5
' 0: 0
' 1042: 412
' 32767: 7FFF
Formato e cultura
Geralmente, os objetos na lista de argumentos são convertidos em suas representações de cadeia de caracteres usando as convenções da cultura atual, que é retornada pela CultureInfo.CurrentCulture propriedade. Você pode controlar esse comportamento chamando uma das sobrecargas de Format que inclui um provider
parâmetro. O provider
parâmetro é uma IFormatProvider implementação que fornece informações de formatação personalizadas e específicas da cultura que são usadas para moderar o processo de formatação.
A IFormatProvider interface tem um único membro, GetFormat, que é responsável por retornar o objeto que fornece informações de formatação. O .NET tem três IFormatProvider implementações que fornecem formatação específica da cultura:
- CultureInfo. Seu GetFormat método retorna um objeto específico NumberFormatInfo de cultura para formatar valores numéricos e um objeto específico DateTimeFormatInfo de cultura para formatar valores de data e hora.
- DateTimeFormatInfo, que é usado para formatação específica da cultura de valores de data e hora. Seu GetFormat método retorna a si mesmo.
- NumberFormatInfo, que é usado para formatação específica da cultura de valores numéricos. Seu GetFormat(Type) método retorna a si mesmo.
Operações de formatação personalizadas
Você também pode chamar qualquer uma das sobrecargas do Format método que têm um provider
parâmetro de tipo IFormatProvider para executar operações de formatação personalizadas. Por exemplo, você pode formatar um inteiro como um número de identificação ou como um número de telefone. Para executar a formatação personalizada, seu provider
argumento deve implementar as IFormatProvider interfaces e ICustomFormatter . Quando o Format método é passado uma ICustomFormatter implementação como o provider
argumento, o Format método chama sua IFormatProvider.GetFormat implementação e solicita um objeto do tipo ICustomFormatter. Em seguida, ele chama o método do objeto retornado ICustomFormatter para formatar cada item de Format formato na cadeia de caracteres composta passada para ele.
Para obter mais informações sobre como fornecer soluções de formatação personalizadas, consulte Como: Definir e usar provedores de formato numérico personalizado e ICustomFormatter. Para obter um exemplo que converte inteiros em números personalizados formatados, consulte Exemplo: uma operação de formatação personalizada. Para obter um exemplo que converte bytes não assinados em algarismos romanos, consulte Exemplo: um provedor de interceptação e formatador de algarismos romanos.
Exemplo: uma operação de formatação personalizada
Este exemplo define um provedor de formato que formata um valor inteiro como um número de conta de cliente no formato x-xxxxx-xx.
using System;
public class TestFormatter
{
public static void Main()
{
int acctNumber = 79203159;
Console.WriteLine(String.Format(new CustomerFormatter(), "{0}", acctNumber));
Console.WriteLine(String.Format(new CustomerFormatter(), "{0:G}", acctNumber));
Console.WriteLine(String.Format(new CustomerFormatter(), "{0:S}", acctNumber));
Console.WriteLine(String.Format(new CustomerFormatter(), "{0:P}", acctNumber));
try {
Console.WriteLine(String.Format(new CustomerFormatter(), "{0:X}", acctNumber));
}
catch (FormatException e) {
Console.WriteLine(e.Message);
}
}
}
public class CustomerFormatter : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
return this;
else
return null;
}
public string Format(string format,
object arg,
IFormatProvider formatProvider)
{
if (! this.Equals(formatProvider))
{
return null;
}
else
{
if (String.IsNullOrEmpty(format))
format = "G";
string customerString = arg.ToString();
if (customerString.Length < 8)
customerString = customerString.PadLeft(8, '0');
format = format.ToUpper();
switch (format)
{
case "G":
return customerString.Substring(0, 1) + "-" +
customerString.Substring(1, 5) + "-" +
customerString.Substring(6);
case "S":
return customerString.Substring(0, 1) + "/" +
customerString.Substring(1, 5) + "/" +
customerString.Substring(6);
case "P":
return customerString.Substring(0, 1) + "." +
customerString.Substring(1, 5) + "." +
customerString.Substring(6);
default:
throw new FormatException(
String.Format("The '{0}' format specifier is not supported.", format));
}
}
}
}
// The example displays the following output:
// 7-92031-59
// 7-92031-59
// 7/92031/59
// 7.92031.59
// The 'X' format specifier is not supported.
open System
type CustomerFormatter() =
interface IFormatProvider with
member this.GetFormat(formatType) =
if formatType = typeof<ICustomFormatter> then
this
else
null
interface ICustomFormatter with
member this.Format(format, arg, formatProvider: IFormatProvider) =
if this.Equals formatProvider |> not then
null
else
let format =
if String.IsNullOrEmpty format then "G"
else format.ToUpper()
let customerString =
let s = string arg
if s.Length < 8 then
s.PadLeft(8, '0')
else s
match format with
| "G" ->
customerString.Substring(0, 1) + "-" +
customerString.Substring(1, 5) + "-" +
customerString.Substring 6
| "S" ->
customerString.Substring(0, 1) + "/" +
customerString.Substring(1, 5) + "/" +
customerString.Substring 6
| "P" ->
customerString.Substring(0, 1) + "." +
customerString.Substring(1, 5) + "." +
customerString.Substring 6
| _ ->
raise (FormatException $"The '{format}' format specifier is not supported.")
let acctNumber = 79203159
String.Format(CustomerFormatter(), "{0}", acctNumber)
|> printfn "%s"
String.Format(CustomerFormatter(), "{0:G}", acctNumber)
|> printfn "%s"
String.Format(CustomerFormatter(), "{0:S}", acctNumber)
|> printfn "%s"
String.Format(CustomerFormatter(), "{0:P}", acctNumber)
|> printfn "%s"
try
String.Format(CustomerFormatter(), "{0:X}", acctNumber)
|> printfn "%s"
with :? FormatException as e ->
printfn $"{e.Message}"
// The example displays the following output:
// 7-92031-59
// 7-92031-59
// 7/92031/59
// 7.92031.59
// The 'X' format specifier is not supported.
Module TestFormatter
Public Sub Main()
Dim acctNumber As Integer = 79203159
Console.WriteLine(String.Format(New CustomerFormatter, "{0}", acctNumber))
Console.WriteLine(String.Format(New CustomerFormatter, "{0:G}", acctNumber))
Console.WriteLine(String.Format(New CustomerFormatter, "{0:S}", acctNumber))
Console.WriteLine(String.Format(New CustomerFormatter, "{0:P}", acctNumber))
Try
Console.WriteLine(String.Format(New CustomerFormatter, "{0:X}", acctNumber))
Catch e As FormatException
Console.WriteLine(e.Message)
End Try
End Sub
End Module
Public Class CustomerFormatter : Implements IFormatProvider, ICustomFormatter
Public Function GetFormat(type As Type) As Object _
Implements IFormatProvider.GetFormat
If type Is GetType(ICustomFormatter) Then
Return Me
Else
Return Nothing
End If
End Function
Public Function Format(fmt As String, _
arg As Object, _
formatProvider As IFormatProvider) As String _
Implements ICustomFormatter.Format
If Not Me.Equals(formatProvider) Then
Return Nothing
Else
If String.IsNullOrEmpty(fmt) Then fmt = "G"
Dim customerString As String = arg.ToString()
if customerString.Length < 8 Then _
customerString = customerString.PadLeft(8, "0"c)
Select Case fmt
Case "G"
Return customerString.Substring(0, 1) & "-" & _
customerString.Substring(1, 5) & "-" & _
customerString.Substring(6)
Case "S"
Return customerString.Substring(0, 1) & "/" & _
customerString.Substring(1, 5) & "/" & _
customerString.Substring(6)
Case "P"
Return customerString.Substring(0, 1) & "." & _
customerString.Substring(1, 5) & "." & _
customerString.Substring(6)
Case Else
Throw New FormatException( _
String.Format("The '{0}' format specifier is not supported.", fmt))
End Select
End If
End Function
End Class
' The example displays the following output:
' 7-92031-59
' 7-92031-59
' 7/92031/59
' 7.92031.59
' The 'X' format specifier is not supported.
Exemplo: um provedor de interceptação e um formatador de numeração romana
Este exemplo define um provedor de formato personalizado que implementa as ICustomFormatter interfaces e IFormatProvider para fazer duas coisas:
Ele exibe os parâmetros passados para sua ICustomFormatter.Format implementação. Isso nos permite ver quais parâmetros o Format(IFormatProvider, String, Object[]) método está passando para a implementação de formatação personalizada para cada objeto que ele tenta formatar. Isso pode ser útil quando você estiver depurando seu aplicativo.
Se o objeto a ser formatado for um valor de byte não assinado que deve ser formatado usando a cadeia de caracteres de formato padrão "R", o formatador personalizado formatará o valor numérico como um algarismo romano.
using System;
using System.Globalization;
public class InterceptProvider : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
return this;
else
return null;
}
public string Format(String format, Object obj, IFormatProvider provider)
{
// Display information about method call.
string formatString = format ?? "<null>";
Console.WriteLine("Provider: {0}, Object: {1}, Format String: {2}",
provider.GetType().Name, obj ?? "<null>", formatString);
if (obj == null) return String.Empty;
// If this is a byte and the "R" format string, format it with Roman numerals.
if (obj is Byte && formatString.ToUpper().Equals("R")) {
Byte value = (Byte) obj;
int remainder;
int result;
String returnString = String.Empty;
// Get the hundreds digit(s)
result = Math.DivRem(value, 100, out remainder);
if (result > 0)
returnString = new String('C', result);
value = (Byte) remainder;
// Get the 50s digit
result = Math.DivRem(value, 50, out remainder);
if (result == 1)
returnString += "L";
value = (Byte) remainder;
// Get the tens digit.
result = Math.DivRem(value, 10, out remainder);
if (result > 0)
returnString += new String('X', result);
value = (Byte) remainder;
// Get the fives digit.
result = Math.DivRem(value, 5, out remainder);
if (result > 0)
returnString += "V";
value = (Byte) remainder;
// Add the ones digit.
if (remainder > 0)
returnString += new String('I', remainder);
// Check whether we have too many X characters.
int pos = returnString.IndexOf("XXXX");
if (pos >= 0) {
int xPos = returnString.IndexOf("L");
if (xPos >= 0 & xPos == pos - 1)
returnString = returnString.Replace("LXXXX", "XC");
else
returnString = returnString.Replace("XXXX", "XL");
}
// Check whether we have too many I characters
pos = returnString.IndexOf("IIII");
if (pos >= 0)
if (returnString.IndexOf("V") >= 0)
returnString = returnString.Replace("VIIII", "IX");
else
returnString = returnString.Replace("IIII", "IV");
return returnString;
}
// Use default for all other formatting.
if (obj is IFormattable)
return ((IFormattable) obj).ToString(format, CultureInfo.CurrentCulture);
else
return obj.ToString();
}
}
public class Example
{
public static void Main()
{
int n = 10;
double value = 16.935;
DateTime day = DateTime.Now;
InterceptProvider provider = new InterceptProvider();
Console.WriteLine(String.Format(provider, "{0:N0}: {1:C2} on {2:d}\n", n, value, day));
Console.WriteLine(String.Format(provider, "{0}: {1:F}\n", "Today: ",
(DayOfWeek) DateTime.Now.DayOfWeek));
Console.WriteLine(String.Format(provider, "{0:X}, {1}, {2}\n",
(Byte) 2, (Byte) 12, (Byte) 199));
Console.WriteLine(String.Format(provider, "{0:R}, {1:R}, {2:R}\n",
(Byte) 2, (Byte) 12, (Byte) 199));
}
}
// The example displays the following output:
// Provider: InterceptProvider, Object: 10, Format String: N0
// Provider: InterceptProvider, Object: 16.935, Format String: C2
// Provider: InterceptProvider, Object: 1/31/2013 6:10:28 PM, Format String: d
// 10: $16.94 on 1/31/2013
//
// Provider: InterceptProvider, Object: Today: , Format String: <null>
// Provider: InterceptProvider, Object: Thursday, Format String: F
// Today: : Thursday
//
// Provider: InterceptProvider, Object: 2, Format String: X
// Provider: InterceptProvider, Object: 12, Format String: <null>
// Provider: InterceptProvider, Object: 199, Format String: <null>
// 2, 12, 199
//
// Provider: InterceptProvider, Object: 2, Format String: R
// Provider: InterceptProvider, Object: 12, Format String: R
// Provider: InterceptProvider, Object: 199, Format String: R
// II, XII, CXCIX
open System
open System.Globalization
type InterceptProvider() =
interface IFormatProvider with
member this.GetFormat(formatType) =
if formatType = typeof<ICustomFormatter> then
this
else
null
interface ICustomFormatter with
member _.Format(format, obj, provider: IFormatProvider) =
// Display information about method call.
let formatString =
if format = null then "<null>" else format
printfn $"Provider: {provider.GetType().Name}, Object: %A{obj}, Format String: %s{formatString}"
if obj = null then
String.Empty
else
// If this is a byte and the "R" format string, format it with Roman numerals.
match obj with
| :? byte as value when formatString.ToUpper().Equals "R" ->
let mutable returnString = String.Empty
// Get the hundreds digit(s)
let struct (result, remainder) = Math.DivRem(value, 100uy)
if result > 0uy then
returnString <- String('C', int result)
let value = byte remainder
// Get the 50s digit
let struct (result, remainder) = Math.DivRem(value, 50uy)
if result = 1uy then
returnString <- returnString + "L"
let value = byte remainder
// Get the tens digit.
let struct (result, remainder) = Math.DivRem(value, 10uy)
if result > 0uy then
returnString <- returnString + String('X', int result)
let value = byte remainder
// Get the fives digit.
let struct (result, remainder) = Math.DivRem(value, 5uy)
if result > 0uy then
returnString <- returnString + "V"
let value = byte remainder
// Add the ones digit.
if remainder > 0uy then
returnString <- returnString + String('I', int remainder)
// Check whether we have too many X characters.
let pos = returnString.IndexOf "XXXX"
if pos >= 0 then
let xPos = returnString.IndexOf "L"
returnString <-
if xPos >= 0 && xPos = pos - 1 then
returnString.Replace("LXXXX", "XC")
else
returnString.Replace("XXXX", "XL")
// Check whether we have too many I characters
let pos = returnString.IndexOf "IIII"
if pos >= 0 then
returnString <-
if returnString.IndexOf "V" >= 0 then
returnString.Replace("VIIII", "IX")
else
returnString.Replace("IIII", "IV")
returnString
// Use default for all other formatting.
| :? IFormattable as x ->
x.ToString(format, CultureInfo.CurrentCulture)
| _ ->
string obj
let n = 10
let value = 16.935
let day = DateTime.Now
let provider = InterceptProvider()
String.Format(provider, "{0:N0}: {1:C2} on {2:d}\n", n, value, day)
|> printfn "%s"
String.Format(provider, "{0}: {1:F}\n", "Today: ", DateTime.Now.DayOfWeek)
|> printfn "%s"
String.Format(provider, "{0:X}, {1}, {2}\n", 2uy, 12uy, 199uy)
|> printfn "%s"
String.Format(provider, "{0:R}, {1:R}, {2:R}\n", 2uy, 12uy, 199uy)
|> printfn "%s"
// The example displays the following output:
// Provider: InterceptProvider, Object: 10, Format String: N0
// Provider: InterceptProvider, Object: 16.935, Format String: C2
// Provider: InterceptProvider, Object: 1/31/2013 6:10:28 PM, Format String: d
// 10: $16.94 on 1/31/2013
//
// Provider: InterceptProvider, Object: Today: , Format String: <null>
// Provider: InterceptProvider, Object: Thursday, Format String: F
// Today: : Thursday
//
// Provider: InterceptProvider, Object: 2, Format String: X
// Provider: InterceptProvider, Object: 12, Format String: <null>
// Provider: InterceptProvider, Object: 199, Format String: <null>
// 2, 12, 199
//
// Provider: InterceptProvider, Object: 2, Format String: R
// Provider: InterceptProvider, Object: 12, Format String: R
// Provider: InterceptProvider, Object: 199, Format String: R
// II, XII, CXCIX
Imports System.Globalization
Public Class InterceptProvider : Implements IFormatProvider, ICustomFormatter
Public Function GetFormat(formatType As Type) As Object _
Implements IFormatProvider.GetFormat
If formatType Is GetType(ICustomFormatter) Then
Return Me
Else
Return Nothing
End If
End Function
Public Function Format(fmt As String, obj As Object, provider As IFormatProvider) As String _
Implements ICustomFormatter.Format
Dim formatString As String = If(fmt IsNot Nothing, fmt, "<null>")
Console.WriteLine("Provider: {0}, Object: {1}, Format String: {2}",
provider, If(obj IsNot Nothing, obj, "<null>"), formatString)
If obj Is Nothing Then Return String.Empty
' If this is a byte and the "R" format string, format it with Roman numerals.
If TypeOf(obj) Is Byte AndAlso formatString.ToUpper.Equals("R") Then
Dim value As Byte = CByte(obj)
Dim remainder As Integer
Dim result As Integer
Dim returnString As String = String.Empty
' Get the hundreds digit(s)
result = Math.DivRem(value, 100, remainder)
If result > 0 Then returnString = New String("C"c, result)
value = CByte(remainder)
' Get the 50s digit
result = Math.DivRem(value, 50, remainder)
If result = 1 Then returnString += "L"
value = CByte(remainder)
' Get the tens digit.
result = Math.DivRem(value, 10, remainder)
If result > 0 Then returnString += New String("X"c, result)
value = CByte(remainder)
' Get the fives digit.
result = Math.DivRem(value, 5, remainder)
If result > 0 Then returnString += "V"
value = CByte(remainder)
' Add the ones digit.
If remainder > 0 Then returnString += New String("I"c, remainder)
' Check whether we have too many X characters.
Dim pos As Integer = returnString.IndexOf("XXXX")
If pos >= 0 Then
Dim xPos As Integer = returnString.IndexOf("L")
If xPos >= 0 And xPos = pos - 1 Then
returnString = returnString.Replace("LXXXX", "XC")
Else
returnString = returnString.Replace("XXXX", "XL")
End If
End If
' Check whether we have too many I characters
pos = returnString.IndexOf("IIII")
If pos >= 0 Then
If returnString.IndexOf("V") >= 0 Then
returnString = returnString.Replace("VIIII", "IX")
Else
returnString = returnString.Replace("IIII", "IV")
End If
End If
Return returnString
End If
' Use default for all other formatting.
If obj Is GetType(IFormattable)
Return CType(obj, IFormattable).ToString(fmt, CultureInfo.CurrentCulture)
Else
Return obj.ToString()
End If
End Function
End Class
Module Example
Public Sub Main()
Dim n As Integer = 10
Dim value As Double = 16.935
Dim day As DateTime = Date.Now
Dim provider As New InterceptProvider()
Console.WriteLine(String.Format(provider, "{0:N0}: {1:C2} on {2:d}", n, value, day))
Console.WriteLine()
Console.WriteLine(String.Format(provider, "{0}: {1:F}", "Today",
CType(Date.Now.DayOfWeek, DayOfWeek)))
Console.WriteLine()
Console.WriteLine(String.Format(provider, "{0:X}, {1}, {2}\n",
CByte(2), CByte(12), CByte(199)))
Console.WriteLine()
Console.WriteLine(String.Format(provider, "{0:R}, {1:R}, {2:R}",
CByte(2), CByte(12), CByte(199)))
End Sub
End Module
' The example displays the following output:
' Provider: InterceptProvider, Object: 10, Format String: N0
' Provider: InterceptProvider, Object: 16.935, Format String: C2
' Provider: InterceptProvider, Object: 1/31/2013 6:10:28 PM, Format String: d
' 10: $16.94 on 1/31/2013
'
' Provider: InterceptProvider, Object: Today: , Format String: <null>
' Provider: InterceptProvider, Object: Thursday, Format String: F
' Today: : Thursday
'
' Provider: InterceptProvider, Object: 2, Format String: X
' Provider: InterceptProvider, Object: 12, Format String: <null>
' Provider: InterceptProvider, Object: 199, Format String: <null>
' 2, 12, 199
'
' Provider: InterceptProvider, Object: 2, Format String: R
' Provider: InterceptProvider, Object: 12, Format String: R
' Provider: InterceptProvider, Object: 199, Format String: R
' II, XII, CXCIX
Perguntas frequentes
Por que você recomenda a interpolação de cadeia de caracteres sobre chamadas para o String.Format
método?
A interpolação de cadeia de caracteres é:
Mais flexível. Ele pode ser usado em qualquer cadeia de caracteres sem exigir uma chamada para um método que ofereça suporte à formatação composta. Caso contrário, você precisará chamar o Format método ou outro método que ofereça suporte à formatação composta, como Console.WriteLine ou StringBuilder.AppendFormat.
Mais legível. Como a expressão a ser inserida em uma cadeia de caracteres aparece na expressão interpolada em vez de em uma lista de argumentos, as cadeias de caracteres interpoladas são muito mais fáceis de codificar e ler. Devido à sua maior legibilidade, as cadeias de caracteres interpoladas podem substituir não apenas chamadas para métodos de formato composto, mas também podem ser usadas em operações de concatenação de cadeia de caracteres para produzir código mais conciso e claro.
Uma comparação dos dois exemplos de código a seguir ilustra a superioridade de cadeias de caracteres interpoladas sobre concatenação de cadeia de caracteres e chamadas para métodos de formatação composta. O uso de várias operações de concatenação de cadeia de caracteres no exemplo a seguir produz código detalhado e difícil de ler.
string[] names = { "Balto", "Vanya", "Dakota", "Samuel", "Koani", "Yiska", "Yuma" };
string output = names[0] + ", " + names[1] + ", " + names[2] + ", " +
names[3] + ", " + names[4] + ", " + names[5] + ", " +
names[6];
output += "\n";
var date = DateTime.Now;
output += String.Format("It is {0:t} on {0:d}. The day of the week is {1}.",
date, date.DayOfWeek);
Console.WriteLine(output);
// The example displays the following output:
// Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
// It is 10:29 AM on 1/8/2018. The day of the week is Monday.
open System
let names = [| "Balto"; "Vanya"; "Dakota"; "Samuel"; "Koani"; "Yiska"; "Yuma" |]
let output =
names[0] + ", " + names[1] + ", " + names[2] + ", " +
names[3] + ", " + names[4] + ", " + names[5] + ", " +
names[6] + "\n"
let date = DateTime.Now
output + String.Format("It is {0:t} on {0:d}. The day of the week is {1}.", date, date.DayOfWeek)
|> printfn "%s"
// The example displays the following output:
// Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
// It is 10:29 AM on 1/8/2018. The day of the week is Monday.
Module Example12
Public Sub Main()
Dim names = {"Balto", "Vanya", "Dakota", "Samuel", "Koani", "Yiska", "Yuma"}
Dim output = names(0) + ", " + names(1) + ", " + names(2) + ", " +
names(3) + ", " + names(4) + ", " + names(5) + ", " +
names(6)
output += vbCrLf
Dim dat = DateTime.Now
output += String.Format("It is {0:t} on {0:d}. The day of the week is {1}.",
dat, dat.DayOfWeek)
Console.WriteLine(output)
End Sub
End Module
' The example displays the following output:
' Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
' It is 10:29 AM on 1/8/2018. The day of the week is Monday.
Por outro lado, o uso de cadeias de caracteres interpoladas no exemplo a seguir produz um código muito mais claro e conciso do que a instrução de concatenação de cadeia de caracteres e a chamada para o Format método no exemplo anterior.
string[] names = { "Balto", "Vanya", "Dakota", "Samuel", "Koani", "Yiska", "Yuma" };
string output = $"{names[0]}, {names[1]}, {names[2]}, {names[3]}, {names[4]}, " +
$"{names[5]}, {names[6]}";
var date = DateTime.Now;
output += $"\nIt is {date:t} on {date:d}. The day of the week is {date.DayOfWeek}.";
Console.WriteLine(output);
// The example displays the following output:
// Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
// It is 10:29 AM on 1/8/2018. The day of the week is Monday.
open System
let names = [| "Balto"; "Vanya"; "Dakota"; "Samuel"; "Koani"; "Yiska"; "Yuma" |]
let output = $"{names[0]}, {names[1]}, {names[2]}, {names[3]}, {names[4]}, {names[5]}, {names[6]}"
let date = DateTime.Now
output + $"\nIt is {date:t} on {date:d}. The day of the week is {date.DayOfWeek}."
|> printfn "%s"
// The example displays the following output:
// Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
// It is 10:29 AM on 1/8/2018. The day of the week is Monday.
Module Example13
Public Sub Main()
Dim names = {"Balto", "Vanya", "Dakota", "Samuel", "Koani", "Yiska", "Yuma"}
Dim output = $"{names(0)}, {names(1)}, {names(2)}, {names(3)}, {names(4)}, " +
$"{names(5)}, {names(6)}"
Dim dat = DateTime.Now
output += $"{vbCrLf}It is {dat:t} on {dat:d}. The day of the week is {dat.DayOfWeek}."
Console.WriteLine(output)
End Sub
End Module
' The example displays the following output:
' Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
' It is 10:29 AM on 1/8/2018. The day of the week is Monday.
Onde posso encontrar as cadeias de caracteres de formato predefinidas?
Para todos os tipos integrais e de ponto flutuante, consulte Cadeias de caracteres de formato numérico padrão e Cadeias de caracteres de formato numérico personalizado.
Para obter valores de data e hora, consulte Cadeias de caracteres de formato de data e hora padrão e Cadeias de caracteres de formato de data e hora personalizadas.
Para valores de enumeração, consulte Cadeias de caracteres de formato de enumeração.
Para TimeSpan obter valores, consulte Cadeias de caracteres de formato TimeSpan padrão e Cadeias de caracteres de formato TimeSpan personalizadas.
Para Guid obter valores, consulte a seção Comentários da página de Guid.ToString(String) referência.
Como posso controlar o alinhamento das cadeias de caracteres de resultado que substituem os itens de formato?
A sintaxe geral de um item de formato é:
{index[,alignment][: formatString]}
onde alinhamento é um inteiro assinado que define a largura do campo. Se esse valor for negativo, o texto no campo será alinhado à esquerda. Se for positivo, o texto é alinhado à direita.
Como posso controlar o número de dígitos após o separador decimal?
Todas as cadeias de caracteres de formato numérico padrão, exceto "D" (que é usado apenas com inteiros), "G", "R" e "X", permitem um especificador de precisão que define o número de dígitos decimais na cadeia de caracteres de resultado. O exemplo a seguir usa cadeias de caracteres de formato numérico padrão para controlar o número de dígitos decimais na cadeia de caracteres de resultado.
object[] values = { 1603, 1794.68235, 15436.14 };
string result;
foreach (var value in values)
{
result = String.Format("{0,12:C2} {0,12:E3} {0,12:F4} {0,12:N3} {1,12:P2}\n",
Convert.ToDouble(value), Convert.ToDouble(value) / 10000);
Console.WriteLine(result);
}
// The example displays output like the following:
// $1,603.00 1.603E+003 1603.0000 1,603.000 16.03 %
//
// $1,794.68 1.795E+003 1794.6824 1,794.682 17.95 %
//
// $15,436.14 1.544E+004 15436.1400 15,436.140 154.36 %
open System
let values: obj list = [ 1603, 1794.68235, 15436.14 ]
for value in values do
String.Format("{0,12:C2} {0,12:E3} {0,12:F4} {0,12:N3} {1,12:P2}\n", Convert.ToDouble(value), Convert.ToDouble(value) / 10000.)
|> printfn "%s"
// The example displays output like the following:
// $1,603.00 1.603E+003 1603.0000 1,603.000 16.03 %
//
// $1,794.68 1.795E+003 1794.6824 1,794.682 17.95 %
//
// $15,436.14 1.544E+004 15436.1400 15,436.140 154.36 %
Module Example7
Public Sub Main()
Dim values() As Object = {1603, 1794.68235, 15436.14}
Dim result As String
For Each value In values
result = String.Format("{0,12:C2} {0,12:E3} {0,12:F4} {0,12:N3} {1,12:P2}",
value, CDbl(value) / 10000)
Console.WriteLine(result)
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output:
' $1,603.00 1.603E+003 1603.0000 1,603.000 16.03 %
'
' $1,794.68 1.795E+003 1794.6824 1,794.682 17.95 %
'
' $15,436.14 1.544E+004 15436.1400 15,436.140 154.36 %
Se você estiver usando uma cadeia de caracteres de formato numérico personalizada, use o especificador de formato "0" para controlar o número de dígitos decimais na cadeia de caracteres de resultado, como mostra o exemplo a seguir.
decimal value = 16309.5436m;
string result = String.Format("{0,12:#.00000} {0,12:0,000.00} {0,12:000.00#}",
value);
Console.WriteLine(result);
// The example displays the following output:
// 16309.54360 16,309.54 16309.544
let value = 16309.5436m
String.Format("{0,12:#.00000} {0,12:0,000.00} {0,12:000.00#}", value)
|> printfn "%s"
// The example displays the following output:
// 16309.54360 16,309.54 16309.544
Module Example8
Public Sub Main()
Dim value As Decimal = 16309.5436D
Dim result As String = String.Format("{0,12:#.00000} {0,12:0,000.00} {0,12:000.00#}",
value)
Console.WriteLine(result)
End Sub
End Module
' The example displays the following output:
' 16309.54360 16,309.54 16309.544
Como posso controlar o número de dígitos integrais?
Por padrão, as operações de formatação exibem apenas dígitos integrais diferentes de zero. Se você estiver formatando inteiros, poderá usar um especificador de precisão com as cadeias de caracteres de formato padrão "D" e "X" para controlar o número de dígitos.
int value = 1326;
string result = String.Format("{0,10:D6} {0,10:X8}", value);
Console.WriteLine(result);
// The example displays the following output:
// 001326 0000052E
open System
let value = 1326
String.Format("{0,10:D6} {0,10:X8}", value)
|> printfn "%s"
// The example displays the following output:
// 001326 0000052E
Module Example10
Public Sub Main()
Dim value As Integer = 1326
Dim result As String = String.Format("{0,10:D6} {0,10:X8}", value)
Console.WriteLine(result)
End Sub
End Module
' The example displays the following output:
' 001326 0000052E
Você pode preencher um número inteiro ou de ponto flutuante com zeros à esquerda para produzir uma cadeia de caracteres de resultado com um número especificado de dígitos integrais usando o especificador de formato numérico personalizado "0", como mostra o exemplo a seguir.
int value = 16342;
string result = String.Format("{0,18:00000000} {0,18:00000000.000} {0,18:000,0000,000.0}",
value);
Console.WriteLine(result);
// The example displays the following output:
// 00016342 00016342.000 0,000,016,342.0
open System
let value = 16342
String.Format("{0,18:00000000} {0,18:00000000.000} {0,18:000,0000,000.0}", value)
|> printfn "%s"
// The example displays the following output:
// 00016342 00016342.000 0,000,016,342.0
Module Example9
Public Sub Main()
Dim value As Integer = 16342
Dim result As String = String.Format("{0,18:00000000} {0,18:00000000.000} {0,18:000,0000,000.0}",
value)
Console.WriteLine(result)
End Sub
End Module
' The example displays the following output:
' 00016342 00016342.000 0,000,016,342.0
Quantos itens posso incluir na lista de formatos?
Não há limite prático. O segundo parâmetro do método é marcado com o ParamArrayAttribute atributo , que permite incluir uma lista delimitada ou uma matriz de objetos como sua lista de Format(IFormatProvider, String, Object[]) formatos.
Como incluir chaves literais ("{" e "}") na cadeia de caracteres de resultados?
Por exemplo, como você impede que a chamada de método a seguir lance uma FormatException exceção?
result = String.Format("The text has {0} '{' characters and {1} '}' characters.",
nOpen, nClose);
let result =
String.Format("The text has {0} '{' characters and {1} '}' characters.", nOpen, nClose)
result = String.Format("The text has {0} '{' characters and {1} '}' characters.",
nOpen, nClose)
Uma única chave de abertura ou fechamento é sempre interpretada como o início ou o fim de um item de formato. Para ser interpretada literalmente, é preciso fugir. Você escapa de uma chave adicionando outra chave ("{{" e "}}" em vez de "{" e "}"), como na seguinte chamada de método:
string result;
int nOpen = 1;
int nClose = 2;
result = String.Format("The text has {0} '{{' characters and {1} '}}' characters.",
nOpen, nClose);
Console.WriteLine(result);
let result =
String.Format("The text has {0} '{{' characters and {1} '}}' characters.", nOpen, nClose)
result = String.Format("The text has {0} '{{' characters and {1} '}}' characters.",
nOpen, nClose)
No entanto, mesmo aparelhos escapados são facilmente mal interpretados. Recomendamos que você inclua chaves na lista de formatos e use itens de formato para inseri-los na cadeia de caracteres de resultados, como mostra o exemplo a seguir.
string result;
int nOpen = 1;
int nClose = 2;
result = String.Format("The text has {0} '{1}' characters and {2} '{3}' characters.",
nOpen, "{", nClose, "}");
Console.WriteLine(result);
let result =
String.Format("The text has {0} '{1}' characters and {2} '{3}' characters.", nOpen, "{", nClose, "}")
result = String.Format("The text has {0} '{1}' characters and {2} '{3}' characters.",
nOpen, "{", nClose, "}")
Por que minha chamada para o método String.Format lança um FormatException?
A causa mais comum da exceção é que o índice de um item de formato não corresponde a um objeto na lista de formatos. Normalmente, isso indica que você numerou incorretamente os índices de itens de formato ou esqueceu de incluir um objeto na lista de formatos. A tentativa de incluir um caractere de chave esquerda ou direita não escapado também lança um FormatExceptionarquivo . Ocasionalmente, a exceção é o resultado de um erro de digitação; Por exemplo, um erro típico é digitar incorretamente "[" (o colchete esquerdo) em vez de "{" (o colchete esquerdo).
Se o método Format(System.IFormatProvider,System.String,System.Object[]) oferece suporte a matrizes de parâmetros, por que meu código lança uma exceção quando uso uma matriz?
Por exemplo, o código a seguir lança uma FormatException exceção:
Random rnd = new Random();
int[] numbers = new int[4];
int total = 0;
for (int ctr = 0; ctr <= 2; ctr++)
{
int number = rnd.Next(1001);
numbers[ctr] = number;
total += number;
}
numbers[3] = total;
Console.WriteLine("{0} + {1} + {2} = {3}", numbers);
open System
let rnd = Random()
let mutable total = 0
let numbers = Array.zeroCreate<int> 4
for i = 0 to 2 do
let number = rnd.Next 1001
numbers[i] <- number
total <- total + number
numbers[3] <- total
Console.WriteLine("{0} + {1} + {2} = {3}", numbers)
Imports System.Collections.Generic
Module Example5
Public Sub Main()
Dim rnd As New Random()
Dim numbers(3) As Integer
Dim total As Integer = 0
For ctr = 0 To 2
Dim number As Integer = rnd.Next(1001)
numbers(ctr) = number
total += number
Next
numbers(3) = total
Console.WriteLine("{0} + {1} + {2} = {3}", numbers)
End Sub
End Module
Este é um problema de resolução de sobrecarga do compilador. Como o compilador não pode converter uma matriz de inteiros em uma matriz de objeto, ele trata a matriz inteira como um único argumento, por isso chama o Format(String, Object) método. A exceção é lançada porque há quatro itens de formato, mas apenas um único item na lista de formatos.
Como nem Visual Basic nem C# pode converter uma matriz inteira em uma matriz de objeto, você precisa executar a conversão antes de chamar o Format(String, Object[]) método. O exemplo a seguir fornece uma implementação.
Random rnd = new Random();
int[] numbers = new int[4];
int total = 0;
for (int ctr = 0; ctr <= 2; ctr++)
{
int number = rnd.Next(1001);
numbers[ctr] = number;
total += number;
}
numbers[3] = total;
object[] values = new object[numbers.Length];
numbers.CopyTo(values, 0);
Console.WriteLine("{0} + {1} + {2} = {3}", values);
open System
let rnd = Random()
let numbers = Array.zeroCreate<int> 4
let mutable total = 0
for i = 0 to 2 do
let number = rnd.Next 1001
numbers[i] <- number
total <- total + number
numbers[3] <- total
let values = Array.zeroCreate<obj> numbers.Length
numbers.CopyTo(values, 0)
Console.WriteLine("{0} + {1} + {2} = {3}", values)
Imports System.Collections.Generic
Module Example6
Public Sub Main()
Dim rnd As New Random()
Dim numbers(3) As Integer
Dim total As Integer = 0
For ctr = 0 To 2
Dim number As Integer = rnd.Next(1001)
numbers(ctr) = number
total += number
Next
numbers(3) = total
Dim values(numbers.Length - 1) As Object
numbers.CopyTo(values, 0)
Console.WriteLine("{0} + {1} + {2} = {3}", values)
End Sub
End Module