Omówienie: Jak formatować liczby, daty, wyliczenia i inne typy na platformie .NET

Formatowanie to proces konwertowania wystąpienia klasy lub struktury albo wartości wyliczenia na reprezentację ciągu. Celem jest wyświetlenie wynikowego ciągu dla użytkowników lub deserializacji go później w celu przywrócenia oryginalnego typu danych. W tym artykule przedstawiono mechanizmy formatowania zapewniane przez platformę .NET.

Uwaga

Analizowanie jest odwrotnością formatowania. Operacja analizowania tworzy wystąpienie typu danych na podstawie reprezentacji ciągu. Aby uzyskać więcej informacji, zobacz Analizowanie ciągów. Aby uzyskać informacje na temat serializacji i deserializacji, zobacz Serializacja na platformie .NET.

Podstawowy mechanizm formatowania to domyślna implementacja Object.ToString metody, która została omówiona w sekcji Formatowanie domyślne przy użyciu metody ToString w dalszej części tego tematu. Jednak platforma .NET udostępnia kilka sposobów modyfikowania i rozszerzania domyślnej obsługi formatowania. Należą do nich następujące funkcje:

  • Przesłanianie Object.ToString metody w celu zdefiniowania niestandardowej reprezentacji ciągu wartości obiektu. Aby uzyskać więcej informacji, zobacz sekcję Zastępowanie metody ToString w dalszej części tego tematu.

  • Definiowanie specyfikatorów formatu, które umożliwiają reprezentację ciągu wartości obiektu w wielu formularzach. Na przykład specyfikator formatu "X" w poniższej instrukcji konwertuje liczbę całkowitą na reprezentację ciągu wartości szesnastkowej.

    int integerValue = 60312;
    Console.WriteLine(integerValue.ToString("X"));   // Displays EB98.
    
    Dim integerValue As Integer = 60312
    Console.WriteLine(integerValue.ToString("X"))   ' Displays EB98.
    

    Aby uzyskać więcej informacji na temat specyfikatorów formatu, zobacz sekcję ToString Method and Format Strings (Metody i formatowania ciągów ).

  • Używanie dostawców formatów do implementowania konwencji formatowania określonej kultury. Na przykład poniższa instrukcja wyświetla wartość waluty przy użyciu konwencji formatowania kultury en-US.

    double cost = 1632.54;
    Console.WriteLine(cost.ToString("C",
                      new System.Globalization.CultureInfo("en-US")));
    // The example displays the following output:
    //       $1,632.54
    
    Dim cost As Double = 1632.54
    Console.WriteLine(cost.ToString("C", New System.Globalization.CultureInfo("en-US")))
    ' The example displays the following output:
    '       $1,632.54
    

    Aby uzyskać więcej informacji na temat formatowania z dostawcami formatów, zobacz sekcję Dostawcy formatów.

  • Implementowanie interfejsu IFormattable w celu obsługi zarówno konwersji ciągów przy użyciu klasy, jak i formatowania złożonego Convert . Aby uzyskać więcej informacji, zobacz sekcję IFormattable Interface (Interfejs IFormattable).

  • Użycie formatowania złożonego w celu osadzenia reprezentacji ciągu wartości w większym ciągu. Aby uzyskać więcej informacji, zobacz sekcję Formatowanie złożone.

  • Korzystając z interpolacji ciągów, bardziej czytelna składnia osadzania reprezentacji ciągu wartości w większym ciągu. Aby uzyskać więcej informacji, zobacz Interpolacja ciągów.

  • Implementowanie ICustomFormatter i IFormatProvider udostępnianie kompletnego rozwiązania do formatowania niestandardowego. Aby uzyskać więcej informacji, zobacz sekcję Custom Formatting with ICustomFormatter (Formatowanie niestandardowe za pomocą formatu ICustomFormatter ).

W poniższych sekcjach przeanalizować te metody konwertowania obiektu na jego reprezentację ciągu.

Formatowanie domyślne przy użyciu metody ToString

Każdy typ pochodzący z System.Object metody automatycznie dziedziczy metodę bez ToString parametrów, która domyślnie zwraca nazwę typu. Poniższy przykład ilustruje metodę domyślną ToString . Definiuje klasę o nazwie Automobile , która nie ma implementacji. Po utworzeniu wystąpienia klasy, a jej ToString metoda jest wywoływana, wyświetla jej nazwę typu. Należy pamiętać, że ToString metoda nie jest jawnie wywoływana w przykładzie. Metoda Console.WriteLine(Object) niejawnie wywołuje metodę ToString obiektu przekazanego do niego jako argument.

using System;

public class Automobile
{
   // No implementation. All members are inherited from Object.
}

public class Example9
{
   public static void Main()
   {
      Automobile firstAuto = new Automobile();
      Console.WriteLine(firstAuto);
   }
}
// The example displays the following output:
//       Automobile
Public Class Automobile
    ' No implementation. All members are inherited from Object.
End Class

Module Example9
    Public Sub Main9()
        Dim firstAuto As New Automobile()
        Console.WriteLine(firstAuto)
    End Sub
End Module
' The example displays the following output:
'       Automobile

Ostrzeżenie

Począwszy od systemu Windows 8.1, środowisko wykonawcze systemu Windows zawiera IStringable interfejs z jedną metodą IStringable.ToString, która zapewnia obsługę formatowania domyślnego. Zalecamy jednak, aby typy zarządzane nie implementują interfejsu IStringable . Aby uzyskać więcej informacji, zobacz sekcję "Środowisko wykonawcze systemu Windows i IStringable interfejs" na stronie referencyjnejObject.ToString.

Ponieważ wszystkie typy inne niż interfejsy pochodzą z Objectprogramu , ta funkcja jest automatycznie dostarczana do niestandardowych klas lub struktur. Jednak funkcjonalność oferowana przez metodę domyślną ToString jest ograniczona: chociaż identyfikuje typ, nie może podać żadnych informacji o wystąpieniu typu. Aby podać reprezentację ciągu obiektu zawierającego informacje o tym obiekcie, należy zastąpić metodę ToString .

Uwaga

Struktury dziedziczą z ValueTypeelementu , który z kolei pochodzi z Objectelementu . Mimo że ValueType zastępuje Object.ToString, jego implementacja jest identyczna.

Zastąpij metodę ToString

Wyświetlanie nazwy typu jest często ograniczone i nie zezwala konsumentom typów na odróżnienie jednego wystąpienia od innego. Można jednak zastąpić metodę ToString , aby zapewnić bardziej przydatną reprezentację wartości obiektu. Poniższy przykład definiuje Temperature obiekt i zastępuje jego ToString metodę w celu wyświetlenia temperatury w stopniach Celsjusza.

public class Temperature
{
    private decimal temp;

    public Temperature(decimal temperature)
    {
        this.temp = temperature;
    }

    public override string ToString()
    {
        return this.temp.ToString("N1") + "°C";
    }
}

public class Example12
{
    public static void Main()
    {
        Temperature currentTemperature = new Temperature(23.6m);
        Console.WriteLine($"The current temperature is {currentTemperature}");
    }
}
// The example displays the following output:
//       The current temperature is 23.6°C.
Public Class Temperature
    Private temp As Decimal

    Public Sub New(temperature As Decimal)
        Me.temp = temperature
    End Sub

    Public Overrides Function ToString() As String
        Return Me.temp.ToString("N1") + "°C"
    End Function
End Class

Module Example13
    Public Sub Main13()
        Dim currentTemperature As New Temperature(23.6D)
        Console.WriteLine("The current temperature is " +
                          currentTemperature.ToString())
    End Sub
End Module
' The example displays the following output:
'       The current temperature is 23.6°C.

Na platformie .NET metoda każdego typu wartości pierwotnej została zastąpiona, ToString aby wyświetlić wartość obiektu zamiast jego nazwy. W poniższej tabeli przedstawiono przesłonięcia dla każdego typu pierwotnego. Należy pamiętać, że większość metod przesłonięć wywołuje kolejne przeciążenie ToString metody i przekazuje do niego specyfikator formatu "G", który definiuje ogólny format dla jego typu, oraz IFormatProvider obiekt reprezentujący bieżącą kulturę.

Typ Przesłonięcia tostring
Boolean Zwraca wartość Boolean.TrueString lub Boolean.FalseString.
Byte Wywołuje metodę Byte.ToString("G", NumberFormatInfo.CurrentInfo) formatowania Byte wartości dla bieżącej kultury.
Char Zwraca znak jako ciąg.
DateTime Wywołuje metodę DateTime.ToString("G", DatetimeFormatInfo.CurrentInfo) formatowania wartości daty i godziny dla bieżącej kultury.
Decimal Wywołuje metodę Decimal.ToString("G", NumberFormatInfo.CurrentInfo) formatowania Decimal wartości dla bieżącej kultury.
Double Wywołuje metodę Double.ToString("G", NumberFormatInfo.CurrentInfo) formatowania Double wartości dla bieżącej kultury.
Int16 Wywołuje metodę Int16.ToString("G", NumberFormatInfo.CurrentInfo) formatowania Int16 wartości dla bieżącej kultury.
Int32 Wywołuje metodę Int32.ToString("G", NumberFormatInfo.CurrentInfo) formatowania Int32 wartości dla bieżącej kultury.
Int64 Wywołuje metodę Int64.ToString("G", NumberFormatInfo.CurrentInfo) formatowania Int64 wartości dla bieżącej kultury.
SByte Wywołuje metodę SByte.ToString("G", NumberFormatInfo.CurrentInfo) formatowania SByte wartości dla bieżącej kultury.
Single Wywołuje metodę Single.ToString("G", NumberFormatInfo.CurrentInfo) formatowania Single wartości dla bieżącej kultury.
UInt16 Wywołuje metodę UInt16.ToString("G", NumberFormatInfo.CurrentInfo) formatowania UInt16 wartości dla bieżącej kultury.
UInt32 Wywołuje metodę UInt32.ToString("G", NumberFormatInfo.CurrentInfo) formatowania UInt32 wartości dla bieżącej kultury.
UInt64 Wywołuje metodę UInt64.ToString("G", NumberFormatInfo.CurrentInfo) formatowania UInt64 wartości dla bieżącej kultury.

Metoda ToString i ciągi formatu

Poleganie na metodzie domyślnej ToString lub zastępowaniu ToString jest odpowiednie, gdy obiekt ma reprezentację pojedynczego ciągu. Jednak wartość obiektu często ma wiele reprezentacji. Na przykład temperatura może być wyrażona w stopniach Fahrenheita, stopni Celsjusza lub kelvins. Podobnie wartość całkowita 10 może być reprezentowana na wiele sposobów, w tym 10, 10,0, 1,0e01 lub 10,00 USD.

Aby umożliwić korzystanie z jednej wartości z wieloma reprezentacjami ciągów, platforma .NET używa ciągów formatu. Ciąg formatu to ciąg zawierający co najmniej jeden wstępnie zdefiniowany specyfikator formatu, które są pojedynczymi znakami lub grupami znaków definiującym sposób ToString formatowania danych wyjściowych metody. Ciąg formatu jest następnie przekazywany jako parametr do metody obiektu i określa sposób wyświetlania ciągu wartości tego obiektu ToString .

Wszystkie typy liczbowe, typy daty i godziny oraz typy wyliczenia na platformie .NET obsługują wstępnie zdefiniowany zestaw specyfikatorów formatu. Możesz również użyć ciągów formatu, aby zdefiniować wiele reprezentacji ciągów typów danych zdefiniowanych przez aplikację.

Standardowe ciągi formatu

Ciąg formatu standardowego zawiera specyfikator pojedynczego formatu, który jest znakiem alfabetycznym, który definiuje reprezentację ciągu obiektu, do którego jest stosowany, wraz z opcjonalnym specyfikatorem dokładności, który wpływa na liczbę cyfr wyświetlanych w ciągu wynikowym. Jeśli specyfikator dokładności zostanie pominięty lub nie jest obsługiwany, specyfikator formatu standardowego jest odpowiednikiem standardowego ciągu formatu.

Platforma .NET definiuje zestaw standardowych specyfikatorów formatu dla wszystkich typów liczbowych, wszystkich typów daty i godziny oraz wszystkich typów wyliczenia. Na przykład każda z tych kategorii obsługuje specyfikator formatu standardowego "G", który definiuje ogólną reprezentację ciągu wartości tego typu.

Standardowe ciągi formatu dla typów wyliczenia bezpośrednio kontrolują reprezentację ciągu wartości. Ciągi formatu przekazywane do metody wartości ToString wyliczenia określają, czy wartość jest wyświetlana przy użyciu jego nazwy ciągu (specyfikatorów formatu "G" i "F"), jego podstawowej wartości całkowitej (specyfikator formatu "D" lub jego wartości szesnastkowej (specyfikator formatu "X"). Poniższy przykład ilustruje użycie standardowych ciągów formatu do formatowania DayOfWeek wartości wyliczenia.

DayOfWeek thisDay = DayOfWeek.Monday;
string[] formatStrings = {"G", "F", "D", "X"};

foreach (string formatString in formatStrings)
   Console.WriteLine(thisDay.ToString(formatString));
// The example displays the following output:
//       Monday
//       Monday
//       1
//       00000001
Dim thisDay As DayOfWeek = DayOfWeek.Monday
Dim formatStrings() As String = {"G", "F", "D", "X"}

For Each formatString As String In formatStrings
    Console.WriteLine(thisDay.ToString(formatString))
Next
' The example displays the following output:
'       Monday
'       Monday
'       1
'       00000001

Aby uzyskać informacje na temat ciągów formatu wyliczenia, zobacz Ciągi formatu wyliczenia.

Standardowe ciągi formatu dla typów liczbowych zwykle definiują ciąg wynikowy, którego dokładny wygląd jest kontrolowany przez co najmniej jedną wartość właściwości. Na przykład specyfikator formatu "C" formatuje liczbę jako wartość waluty. Podczas wywoływania ToString metody z specyfikatorem formatu "C" jako jedynym parametrem są używane następujące wartości właściwości z obiektu bieżącej kultury NumberFormatInfo do zdefiniowania reprezentacji ciągu wartości liczbowej:

  • Właściwość CurrencySymbol , która określa symbol waluty bieżącej kultury.

  • Właściwość CurrencyNegativePattern or CurrencyPositivePattern , która zwraca liczbę całkowitą, która określa następujące elementy:

    • Położenie symbolu waluty.

    • Czy wartości ujemne są wskazywane przez wiodący znak ujemny, końcowy znak ujemny lub nawiasy.

    • Czy odstęp pojawia się między wartością liczbową a symbolem waluty.

  • Właściwość CurrencyDecimalDigits , która definiuje liczbę cyfr ułamkowych w ciągu wynikowym.

  • Właściwość CurrencyDecimalSeparator , która definiuje symbol separatora dziesiętnego w ciągu wynikowym.

  • Właściwość CurrencyGroupSeparator , która definiuje symbol separatora grup.

  • Właściwość CurrencyGroupSizes , która definiuje liczbę cyfr w każdej grupie po lewej stronie dziesiętnej.

  • Właściwość NegativeSign , która określa znak ujemny używany w ciągu wynikowym, jeśli nawiasy nie są używane do wskazywania wartości ujemnych.

Ponadto ciągi formatu liczbowego mogą zawierać specyfikator dokładności. Znaczenie tego specyfikatora zależy od ciągu formatu, z którym jest używany, ale zazwyczaj wskazuje całkowitą liczbę cyfr lub liczbę cyfr ułamkowych, które powinny być wyświetlane w ciągu wynikowym. Na przykład w poniższym przykładzie użyto standardowego ciągu liczbowego "X4" i specyfikatora dokładności do utworzenia wartości ciągu zawierającej cztery cyfry szesnastkowe.

byte[] byteValues = { 12, 163, 255 };
foreach (byte byteValue in byteValues)
   Console.WriteLine(byteValue.ToString("X4"));
// The example displays the following output:
//       000C
//       00A3
//       00FF
Dim byteValues() As Byte = {12, 163, 255}
For Each byteValue As Byte In byteValues
    Console.WriteLine(byteValue.ToString("X4"))
Next
' The example displays the following output:
'       000C
'       00A3
'       00FF

Aby uzyskać więcej informacji na temat standardowych ciągów formatowania liczbowego, zobacz Standardowe ciągi formatu liczbowego.

Standardowe ciągi formatu dla wartości daty i godziny to aliasy ciągów formatu niestandardowego przechowywanych przez określoną DateTimeFormatInfo właściwość. Na przykład wywołanie ToString metody wartości daty i godziny za pomocą specyfikatora formatu "D" wyświetla datę i godzinę przy użyciu niestandardowego ciągu formatu przechowywanego we właściwości bieżącej kultury DateTimeFormatInfo.LongDatePattern . (Aby uzyskać więcej informacji na temat ciągów formatu niestandardowego, zobacz następną sekcję). Poniższy przykład ilustruje tę relację.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      DateTime date1 = new DateTime(2009, 6, 30);
      Console.WriteLine("D Format Specifier:     {0:D}", date1);
      string longPattern = CultureInfo.CurrentCulture.DateTimeFormat.LongDatePattern;
      Console.WriteLine("'{0}' custom format string:     {1}",
                        longPattern, date1.ToString(longPattern));
   }
}
// The example displays the following output when run on a system whose
// current culture is en-US:
//    D Format Specifier:     Tuesday, June 30, 2009
//    'dddd, MMMM dd, yyyy' custom format string:     Tuesday, June 30, 2009
Imports System.Globalization

Module Example
    Public Sub Main0()
        Dim date1 As Date = #6/30/2009#
        Console.WriteLine("D Format Specifier:     {0:D}", date1)
        Dim longPattern As String = CultureInfo.CurrentCulture.DateTimeFormat.LongDatePattern
        Console.WriteLine("'{0}' custom format string:     {1}",
                          longPattern, date1.ToString(longPattern))
    End Sub
End Module
' The example displays the following output when run on a system whose
' current culture is en-US:
'    D Format Specifier:     Tuesday, June 30, 2009
'    'dddd, MMMM dd, yyyy' custom format string:     Tuesday, June 30, 2009

Aby uzyskać więcej informacji na temat standardowych ciągów formatu daty i godziny, zobacz Standardowe ciągi formatu daty i godziny.

Można również użyć standardowych ciągów formatu, aby zdefiniować reprezentację ciągu obiektu zdefiniowanego przez aplikację, który jest generowany przez metodę obiektu ToString(String) . Można zdefiniować określone specyfikatory formatu standardowego obsługiwane przez obiekt i określić, czy są uwzględniane wielkość liter, czy bez uwzględniania wielkości liter. Implementacja ToString(String) metody powinna obsługiwać następujące elementy:

  • Specyfikator formatu "G", który reprezentuje niestandardowy lub wspólny format obiektu. Przeciążenie bez parametrów metody obiektu ToString powinno wywołać jego ToString(String) przeciążenie i przekazać do niego standardowy ciąg formatu "G".

  • Obsługa specyfikatora formatu, który jest równy odwołaniu o wartości null (Nothing w Visual Basic). Specyfikator formatu, który jest równy odwołaniu o wartości null, powinien być traktowany jako odpowiednik specyfikatora formatu "G".

Na przykład klasa może wewnętrznie przechowywać temperaturę Temperature w stopniach Celsjusza i używać specyfikatorów formatu do reprezentowania wartości Temperature obiektu w stopniach Celsjusza, stopni Fahrenheita i kelvins. Poniższy przykład stanowi ilustrację.

using System;

public class Temperature
{
   private decimal m_Temp;

   public Temperature(decimal temperature)
   {
      this.m_Temp = temperature;
   }

   public decimal Celsius
   {
      get { return this.m_Temp; }
   }

   public decimal Kelvin
   {
      get { return this.m_Temp + 273.15m; }
   }

   public decimal Fahrenheit
   {
      get { return Math.Round(((decimal) (this.m_Temp * 9 / 5 + 32)), 2); }
   }

   public override string ToString()
   {
      return this.ToString("C");
   }

   public string ToString(string format)
   {
      // Handle null or empty string.
      if (String.IsNullOrEmpty(format)) format = "C";
      // Remove spaces and convert to uppercase.
      format = format.Trim().ToUpperInvariant();

      // Convert temperature to Fahrenheit and return string.
      switch (format)
      {
         // Convert temperature to Fahrenheit and return string.
         case "F":
            return this.Fahrenheit.ToString("N2") + " °F";
         // Convert temperature to Kelvin and return string.
         case "K":
            return this.Kelvin.ToString("N2") + " K";
         // return temperature in Celsius.
         case "G":
         case "C":
            return this.Celsius.ToString("N2") + " °C";
         default:
            throw new FormatException(String.Format("The '{0}' format string is not supported.", format));
      }
   }
}

public class Example1
{
   public static void Main()
   {
      Temperature temp1 = new Temperature(0m);
      Console.WriteLine(temp1.ToString());
      Console.WriteLine(temp1.ToString("G"));
      Console.WriteLine(temp1.ToString("C"));
      Console.WriteLine(temp1.ToString("F"));
      Console.WriteLine(temp1.ToString("K"));

      Temperature temp2 = new Temperature(-40m);
      Console.WriteLine(temp2.ToString());
      Console.WriteLine(temp2.ToString("G"));
      Console.WriteLine(temp2.ToString("C"));
      Console.WriteLine(temp2.ToString("F"));
      Console.WriteLine(temp2.ToString("K"));

      Temperature temp3 = new Temperature(16m);
      Console.WriteLine(temp3.ToString());
      Console.WriteLine(temp3.ToString("G"));
      Console.WriteLine(temp3.ToString("C"));
      Console.WriteLine(temp3.ToString("F"));
      Console.WriteLine(temp3.ToString("K"));

      Console.WriteLine(String.Format("The temperature is now {0:F}.", temp3));
   }
}
// The example displays the following output:
//       0.00 °C
//       0.00 °C
//       0.00 °C
//       32.00 °F
//       273.15 K
//       -40.00 °C
//       -40.00 °C
//       -40.00 °C
//       -40.00 °F
//       233.15 K
//       16.00 °C
//       16.00 °C
//       16.00 °C
//       60.80 °F
//       289.15 K
//       The temperature is now 16.00 °C.
Public Class Temperature
    Private m_Temp As Decimal

    Public Sub New(temperature As Decimal)
        Me.m_Temp = temperature
    End Sub

    Public ReadOnly Property Celsius() As Decimal
        Get
            Return Me.m_Temp
        End Get
    End Property

    Public ReadOnly Property Kelvin() As Decimal
        Get
            Return Me.m_Temp + 273.15D
        End Get
    End Property

    Public ReadOnly Property Fahrenheit() As Decimal
        Get
            Return Math.Round(CDec(Me.m_Temp * 9 / 5 + 32), 2)
        End Get
    End Property

    Public Overrides Function ToString() As String
        Return Me.ToString("C")
    End Function

    Public Overloads Function ToString(format As String) As String
        ' Handle null or empty string.
        If String.IsNullOrEmpty(format) Then format = "C"
        ' Remove spaces and convert to uppercase.
        format = format.Trim().ToUpperInvariant()

        Select Case format
            Case "F"
                ' Convert temperature to Fahrenheit and return string.
                Return Me.Fahrenheit.ToString("N2") & " °F"
            Case "K"
                ' Convert temperature to Kelvin and return string.
                Return Me.Kelvin.ToString("N2") & " K"
            Case "C", "G"
                ' Return temperature in Celsius.
                Return Me.Celsius.ToString("N2") & " °C"
            Case Else
                Throw New FormatException(String.Format("The '{0}' format string is not supported.", format))
        End Select
    End Function
End Class

Public Module Example1
    Public Sub Main1()
        Dim temp1 As New Temperature(0D)
        Console.WriteLine(temp1.ToString())
        Console.WriteLine(temp1.ToString("G"))
        Console.WriteLine(temp1.ToString("C"))
        Console.WriteLine(temp1.ToString("F"))
        Console.WriteLine(temp1.ToString("K"))

        Dim temp2 As New Temperature(-40D)
        Console.WriteLine(temp2.ToString())
        Console.WriteLine(temp2.ToString("G"))
        Console.WriteLine(temp2.ToString("C"))
        Console.WriteLine(temp2.ToString("F"))
        Console.WriteLine(temp2.ToString("K"))

        Dim temp3 As New Temperature(16D)
        Console.WriteLine(temp3.ToString())
        Console.WriteLine(temp3.ToString("G"))
        Console.WriteLine(temp3.ToString("C"))
        Console.WriteLine(temp3.ToString("F"))
        Console.WriteLine(temp3.ToString("K"))

        Console.WriteLine(String.Format("The temperature is now {0:F}.", temp3))
    End Sub
End Module
' The example displays the following output:
'       0.00 °C
'       0.00 °C
'       0.00 °C
'       32.00 °F
'       273.15 K
'       -40.00 °C
'       -40.00 °C
'       -40.00 °C
'       -40.00 °F
'       233.15 K
'       16.00 °C
'       16.00 °C
'       16.00 °C
'       60.80 °F
'       289.15 K
'       The temperature is now 16.00 °C.

Ciągi formatu niestandardowego

Oprócz standardowych ciągów formatu platforma .NET definiuje niestandardowe ciągi formatu zarówno dla wartości liczbowych, jak i wartości daty i godziny. Ciąg formatu niestandardowego składa się z co najmniej jednego specyfikatora formatu niestandardowego definiującego reprezentację ciągu wartości. Na przykład niestandardowy ciąg formatu daty i godziny "rrrr/mm/dd hh:mm:ss.ffff t zzz" konwertuje datę na reprezentację ciągu w postaci "2008/11/15 07:45:00.000 P -08:000" dla kultury en-US. Podobnie ciąg formatu niestandardowego "0000" konwertuje wartość całkowitą 12 na "0012". Aby uzyskać pełną listę niestandardowych ciągów formatu, zobacz Niestandardowe ciągi formatu daty i godziny oraz niestandardowe ciągi formatu liczbowego.

Jeśli ciąg formatu składa się z jednego specyfikatora formatu niestandardowego, specyfikator formatu powinien być poprzedzony symbolem procentu (%) w celu uniknięcia nieporozumień ze standardowym specyfikatorem formatu. W poniższym przykładzie użyto specyfikatora formatu niestandardowego "M", aby wyświetlić jednocyfrową lub dwucyfrową liczbę miesiąca określonej daty.

DateTime date1 = new DateTime(2009, 9, 8);
Console.WriteLine(date1.ToString("%M"));       // Displays 9
Dim date1 As Date = #09/08/2009#
Console.WriteLine(date1.ToString("%M"))      ' Displays 9

Wiele standardowych ciągów formatu dla wartości daty i godziny to aliasy ciągów formatu niestandardowego DateTimeFormatInfo , które są definiowane przez właściwości obiektu. Niestandardowe ciągi formatu zapewniają również znaczną elastyczność w zapewnieniu formatowania zdefiniowanego przez aplikację dla wartości liczbowych lub wartości daty i godziny. Możesz zdefiniować własne niestandardowe ciągi wyników zarówno dla wartości liczbowych, jak i wartości daty i godziny, łącząc wiele specyfikatorów formatu niestandardowego w jeden ciąg formatu niestandardowego. W poniższym przykładzie zdefiniowano niestandardowy ciąg formatu, który wyświetla dzień tygodnia w nawiasach po nazwie miesiąca, dniu i roku.

string customFormat = "MMMM dd, yyyy (dddd)";
DateTime date1 = new DateTime(2009, 8, 28);
Console.WriteLine(date1.ToString(customFormat));
// The example displays the following output if run on a system
// whose language is English:
//       August 28, 2009 (Friday)
Dim customFormat As String = "MMMM dd, yyyy (dddd)"
Dim date1 As Date = #8/28/2009#
Console.WriteLine(date1.ToString(customFormat))
' The example displays the following output if run on a system
' whose language is English:
'       August 28, 2009 (Friday)      

W poniższym przykładzie zdefiniowano niestandardowy ciąg formatu, który wyświetla Int64 wartość jako standardowy, siedmiocyfrowy numer telefonu USA wraz z jego kodem obszaru.

using System;

public class Example17
{
   public static void Main()
   {
      long number = 8009999999;
      string fmt = "000-000-0000";
      Console.WriteLine(number.ToString(fmt));
   }
}
// The example displays the following output:
//        800-999-9999
Module Example18
    Public Sub Main18()
        Dim number As Long = 8009999999
        Dim fmt As String = "000-000-0000"
        Console.WriteLine(number.ToString(fmt))
    End Sub
End Module
' The example displays the following output:

' The example displays the following output:
'       800-999-9999

Mimo że standardowe ciągi formatu zwykle obsługują większość potrzeb formatowania dla typów zdefiniowanych przez aplikację, można również zdefiniować specyfikatory formatu niestandardowego w celu formatowania typów.

Formatowanie ciągów i typów platformy .NET

Wszystkie typy liczbowe (czyli Byte, , , DoubleInt32Int64Int16SingleUInt16SByteUInt32DecimalUInt64i BigInteger typy), a także DateTimetypy , DateTimeOffset, TimeSpan, , Guidi wszystkich typów wyliczenia, obsługują formatowanie z ciągami formatu. Aby uzyskać informacje na temat określonych ciągów formatu obsługiwanych przez każdy typ, zobacz następujące tematy:

Tytuł Definicja
Standardowe ciągi formatów liczbowych Opisuje standardowe ciągi formatu, które tworzą powszechnie używane reprezentacje ciągów wartości liczbowych.
Niestandardowe ciągi formatujące liczby Opisuje niestandardowe ciągi formatu, które tworzą formaty specyficzne dla aplikacji dla wartości liczbowych.
Standardowe ciągi formatu data i godzina Opisuje standardowe ciągi formatu, które tworzą powszechnie używane reprezentacje ciągów DateTime i DateTimeOffset wartości.
Niestandardowe ciągi formatu data i godzina Opisuje niestandardowe ciągi formatu, które tworzą formaty specyficzne dla aplikacji dla DateTime wartości i DateTimeOffset .
Standardowe ciągi formatujące TimeSpan Opisuje standardowe ciągi formatu, które tworzą powszechnie używane reprezentacje ciągów interwałów czasu.
Niestandardowe ciągi formatujące TimeSpan Opisuje niestandardowe ciągi formatu, które tworzą formaty specyficzne dla aplikacji dla interwałów czasu.
Ciągi formatujące wyliczenia Opisuje standardowe ciągi formatu używane do tworzenia reprezentacji ciągów wartości wyliczenia.
Guid.ToString(String) Opisuje standardowe ciągi formatu dla Guid wartości.

Formatowanie wrażliwe na kulturę przy użyciu dostawców formatów

Chociaż specyfikatory formatu umożliwiają dostosowanie formatowania obiektów, tworzenie znaczącej reprezentacji ciągów obiektów często wymaga dodatkowych informacji o formatowaniu. Na przykład formatowanie liczby jako wartości waluty przy użyciu standardowego ciągu formatu "C" lub niestandardowego ciągu formatu, takiego jak "$ #,#.00", wymaga co najmniej informacji o prawidłowym symbolu waluty, separatorze grupy i separatorze dziesiętnym, które mają być dostępne do uwzględnienia w sformatowanym ciągu. Na platformie .NET te dodatkowe informacje dotyczące formatowania są udostępniane za pośrednictwem interfejsu IFormatProvider , który jest dostarczany jako parametr do co najmniej jednego przeciążenia ToString metody typów liczbowych i typów daty i godziny. IFormatProvider Implementacje są używane na platformie .NET do obsługi formatowania specyficznego dla kultury. W poniższym przykładzie pokazano, jak reprezentacja ciągu obiektu zmienia się w przypadku formatowania z trzema IFormatProvider obiektami reprezentującymi różne kultury.

using System;
using System.Globalization;

public class Example18
{
   public static void Main()
   {
      decimal value = 1603.42m;
      Console.WriteLine(value.ToString("C3", new CultureInfo("en-US")));
      Console.WriteLine(value.ToString("C3", new CultureInfo("fr-FR")));
      Console.WriteLine(value.ToString("C3", new CultureInfo("de-DE")));
   }
}
// The example displays the following output:
//       $1,603.420
//       1 603,420 €
//       1.603,420 €
Imports System.Globalization

Public Module Example11
    Public Sub Main11()
        Dim value As Decimal = 1603.42D
        Console.WriteLine(value.ToString("C3", New CultureInfo("en-US")))
        Console.WriteLine(value.ToString("C3", New CultureInfo("fr-FR")))
        Console.WriteLine(value.ToString("C3", New CultureInfo("de-DE")))
    End Sub
End Module
' The example displays the following output:
'       $1,603.420
'       1 603,420 €
'       1.603,420 €

Interfejs IFormatProvider zawiera jedną metodę , GetFormat(Type)która ma jeden parametr określający typ obiektu, który zapewnia informacje o formatowaniu. Jeśli metoda może podać obiekt tego typu, zwraca go. W przeciwnym razie zwraca odwołanie o wartości null (Nothing w Visual Basic).

IFormatProvider.GetFormat jest metodą wywołania zwrotnego. Wywołanie ToString przeciążenia metody zawierającego IFormatProvider parametr wywołuje metodę GetFormat tego IFormatProvider obiektu. Metoda GetFormat jest odpowiedzialna za zwracanie obiektu, który dostarcza niezbędne informacje formatowania, określone przez jego formatType parametr, do ToString metody .

Wiele metod formatowania lub konwersji ciągów zawiera parametr typu IFormatProvider, ale w wielu przypadkach wartość parametru jest ignorowana podczas wywoływanej metody. W poniższej tabeli wymieniono niektóre metody formatowania, które używają parametru i typu Type obiektu przekazywanego IFormatProvider.GetFormat do metody.

Method Typ parametru formatType
ToString metoda typów liczbowych System.Globalization.NumberFormatInfo
ToString metoda typów daty i godziny System.Globalization.DateTimeFormatInfo
String.Format System.ICustomFormatter
StringBuilder.AppendFormat System.ICustomFormatter

Uwaga

Metody ToString typów liczbowych i typów daty i godziny są przeciążone, a tylko niektóre przeciążenia obejmują IFormatProvider parametr. Jeśli metoda nie ma parametru typu IFormatProvider, obiekt zwracany przez CultureInfo.CurrentCulture właściwość jest przekazywany zamiast tego. Na przykład wywołanie metody domyślnej Int32.ToString() ostatecznie powoduje wywołanie metody, takie jak: Int32.ToString("G", System.Globalization.CultureInfo.CurrentCulture).

Platforma .NET udostępnia trzy klasy, które implementują :IFormatProvider

Możesz również zaimplementować własnego dostawcę formatu, aby zastąpić dowolną z tych klas. Jednak metoda implementacji GetFormat musi zwrócić obiekt typu wymienionego w poprzedniej tabeli, jeśli musi podać informacje ToString o formatowaniu dla metody .

Formatowanie wartości liczbowych uwzględniające kulturę

Domyślnie formatowanie wartości liczbowych jest wrażliwe na kulturę. Jeśli nie określisz kultury podczas wywoływania metody formatowania, używane są konwencje formatowania bieżącej kultury. Przedstawiono to w poniższym przykładzie, który zmienia bieżącą kulturę cztery razy, a następnie wywołuje metodę Decimal.ToString(String) . W każdym przypadku ciąg wynikowy odzwierciedla konwencje formatowania bieżącej kultury. Wynika to z faktu, że ToString metody i ToString(String) zawijają wywołania do metody każdego typu liczbowego ToString(String, IFormatProvider) .

using System.Globalization;

public class Example6
{
   public static void Main()
   {
      string[] cultureNames = { "en-US", "fr-FR", "es-MX", "de-DE" };
      Decimal value = 1043.17m;

      foreach (var cultureName in cultureNames) {
         // Change the current culture.
         CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName);
         Console.WriteLine($"The current culture is {CultureInfo.CurrentCulture.Name}");
         Console.WriteLine(value.ToString("C2"));
         Console.WriteLine();
      }
   }
}
// The example displays the following output:
//       The current culture is en-US
//       $1,043.17
//
//       The current culture is fr-FR
//       1 043,17 €
//
//       The current culture is es-MX
//       $1,043.17
//
//       The current culture is de-DE
//       1.043,17 €
Imports System.Globalization

Module Example6
    Public Sub Main6()
        Dim cultureNames() As String = {"en-US", "fr-FR", "es-MX", "de-DE"}
        Dim value As Decimal = 1043.17D

        For Each cultureName In cultureNames
            ' Change the current culture.
            CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName)
            Console.WriteLine($"The current culture is {CultureInfo.CurrentCulture.Name}")
            Console.WriteLine(value.ToString("C2"))
            Console.WriteLine()
        Next
    End Sub
End Module
' The example displays the following output:
'       The current culture is en-US
'       $1,043.17
'       
'       The current culture is fr-FR
'       1 043,17 €
'       
'       The current culture is es-MX
'       $1,043.17
'       
'       The current culture is de-DE
'       1.043,17 €

Można również sformatować wartość liczbową dla określonej kultury, wywołując ToString przeciążenie, które ma provider parametr i przekazując jedną z następujących wartości:

W poniższym przykładzie użyto NumberFormatInfo obiektów reprezentujących kultury angielskie (Stany Zjednoczone) i angielski (Wielka Brytania) oraz francuskie i rosyjskie neutralne kultury, aby sformatować liczbę zmiennoprzecinkową.

using System.Globalization;

public class Example7
{
    public static void Main()
    {
        double value = 1043.62957;
        string[] cultureNames = { "en-US", "en-GB", "ru", "fr" };

        foreach (string? name in cultureNames)
        {
            NumberFormatInfo nfi = CultureInfo.CreateSpecificCulture(name).NumberFormat;
            Console.WriteLine("{0,-6} {1}", name + ":", value.ToString("N3", nfi));
        }
    }
}
// The example displays the following output:
//       en-US: 1,043.630
//       en-GB: 1,043.630
//       ru:    1 043,630
//       fr:    1 043,630
Imports System.Globalization

Module Example7
    Public Sub Main7()
        Dim value As Double = 1043.62957
        Dim cultureNames() As String = {"en-US", "en-GB", "ru", "fr"}

        For Each name In cultureNames
            Dim nfi As NumberFormatInfo = CultureInfo.CreateSpecificCulture(name).NumberFormat
            Console.WriteLine("{0,-6} {1}", name + ":", value.ToString("N3", nfi))
        Next
    End Sub
End Module
' The example displays the following output:
'       en-US: 1,043.630
'       en-GB: 1,043.630
'       ru:    1 043,630
'       fr:    1 043,630

Formatowanie uwzględniające kulturę wartości daty i godziny

Domyślnie formatowanie wartości daty i godziny jest wrażliwe na kulturę. Jeśli nie określisz kultury podczas wywoływania metody formatowania, używane są konwencje formatowania bieżącej kultury. Przedstawiono to w poniższym przykładzie, który zmienia bieżącą kulturę cztery razy, a następnie wywołuje metodę DateTime.ToString(String) . W każdym przypadku ciąg wynikowy odzwierciedla konwencje formatowania bieżącej kultury. Jest to spowodowane tym, że DateTime.ToString()metody , DateTime.ToString(String), DateTimeOffset.ToString()i DateTimeOffset.ToString(String) zawijają wywołania metod DateTime.ToString(String, IFormatProvider) i DateTimeOffset.ToString(String, IFormatProvider) .

using System.Globalization;

public class Example4
{
   public static void Main()
   {
      string[] cultureNames = { "en-US", "fr-FR", "es-MX", "de-DE" };
      DateTime dateToFormat = new DateTime(2012, 5, 28, 11, 30, 0);

      foreach (var cultureName in cultureNames) {
         // Change the current culture.
         CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName);
         Console.WriteLine($"The current culture is {CultureInfo.CurrentCulture.Name}");
         Console.WriteLine(dateToFormat.ToString("F"));
         Console.WriteLine();
      }
   }
}
// The example displays the following output:
//       The current culture is en-US
//       Monday, May 28, 2012 11:30:00 AM
//
//       The current culture is fr-FR
//       lundi 28 mai 2012 11:30:00
//
//       The current culture is es-MX
//       lunes, 28 de mayo de 2012 11:30:00 a.m.
//
//       The current culture is de-DE
//       Montag, 28. Mai 2012 11:30:00
Imports System.Globalization
Imports System.Threading

Module Example4
    Public Sub Main4()
        Dim cultureNames() As String = {"en-US", "fr-FR", "es-MX", "de-DE"}
        Dim dateToFormat As Date = #5/28/2012 11:30AM#

        For Each cultureName In cultureNames
            ' Change the current culture.
            CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName)
            Console.WriteLine($"The current culture is {CultureInfo.CurrentCulture.Name}")
            Console.WriteLine(dateToFormat.ToString("F"))
            Console.WriteLine()
        Next
    End Sub
End Module
' The example displays the following output:
'       The current culture is en-US
'       Monday, May 28, 2012 11:30:00 AM
'       
'       The current culture is fr-FR
'       lundi 28 mai 2012 11:30:00
'       
'       The current culture is es-MX
'       lunes, 28 de mayo de 2012 11:30:00 a.m.
'       
'       The current culture is de-DE
'       Montag, 28. Mai 2012 11:30:00 

Można również sformatować wartość daty i godziny dla określonej kultury, wywołując DateTime.ToStringDateTimeOffset.ToString lub przeciążenie, które ma provider parametr i przekazując jedną z następujących wartości:

W poniższym przykładzie użyto DateTimeFormatInfo obiektów reprezentujących kultury angielskie (Stany Zjednoczone) i angielski (Wielka Brytania) oraz francuskie i rosyjskie kultury neutralne w celu sformatowania daty.

using System.Globalization;

public class Example5
{
   public static void Main()
   {
      DateTime dat1 = new(2012, 5, 28, 11, 30, 0);
      string[] cultureNames = { "en-US", "en-GB", "ru", "fr" };

      foreach (var name in cultureNames) {
         DateTimeFormatInfo dtfi = CultureInfo.CreateSpecificCulture(name).DateTimeFormat;
         Console.WriteLine($"{name}: {dat1.ToString(dtfi)}");
      }
   }
}
// The example displays the following output:
//       en-US: 5/28/2012 11:30:00 AM
//       en-GB: 28/05/2012 11:30:00
//       ru: 28.05.2012 11:30:00
//       fr: 28/05/2012 11:30:00
Imports System.Globalization

Module Example5
    Public Sub Main5()
        Dim dat1 As Date = #5/28/2012 11:30AM#
        Dim cultureNames() As String = {"en-US", "en-GB", "ru", "fr"}

        For Each name In cultureNames
            Dim dtfi As DateTimeFormatInfo = CultureInfo.CreateSpecificCulture(name).DateTimeFormat
            Console.WriteLine($"{name}: {dat1.ToString(dtfi)}")
        Next
    End Sub
End Module
' The example displays the following output:
'       en-US: 5/28/2012 11:30:00 AM
'       en-GB: 28/05/2012 11:30:00
'       ru: 28.05.2012 11:30:00
'       fr: 28/05/2012 11:30:00

Interfejs IFormattable

Zazwyczaj typy, które przeciążą ToString metodę ciągiem formatu i parametrem IFormatProvider , również implementują IFormattable interfejs. Ten interfejs ma jeden element członkowski , IFormattable.ToString(String, IFormatProvider)który zawiera zarówno ciąg formatu, jak i dostawcę formatu jako parametry.

Implementacja interfejsu IFormattable dla klasy zdefiniowanej przez aplikację ma dwie zalety:

W poniższym przykładzie zdefiniowano klasę Temperature , która implementuje IFormattable interfejs. Obsługuje specyfikatory formatu "C" lub "G", aby wyświetlić temperaturę w stopniach Celsjusza, specyfikator formatu "F", aby wyświetlić temperaturę w Fahrenheita i specyfikator formatu "K", aby wyświetlić temperaturę w Kelvin.

using System;
using System.Globalization;

namespace HotAndCold
{

    public class Temperature : IFormattable
    {
        private decimal m_Temp;

        public Temperature(decimal temperature)
        {
            this.m_Temp = temperature;
        }

        public decimal Celsius
        {
            get { return this.m_Temp; }
        }

        public decimal Kelvin
        {
            get { return this.m_Temp + 273.15m; }
        }

        public decimal Fahrenheit
        {
            get { return Math.Round((decimal)this.m_Temp * 9 / 5 + 32, 2); }
        }

        public override string ToString()
        {
            return this.ToString("G", null);
        }

        public string ToString(string format)
        {
            return this.ToString(format, null);
        }

        public string ToString(string format, IFormatProvider provider)
        {
            // Handle null or empty arguments.
            if (String.IsNullOrEmpty(format))
                format = "G";
            // Remove any white space and covert to uppercase.
            format = format.Trim().ToUpperInvariant();

            if (provider == null)
                provider = NumberFormatInfo.CurrentInfo;

            switch (format)
            {
                // Convert temperature to Fahrenheit and return string.
                case "F":
                    return this.Fahrenheit.ToString("N2", provider) + "°F";
                // Convert temperature to Kelvin and return string.
                case "K":
                    return this.Kelvin.ToString("N2", provider) + "K";
                // Return temperature in Celsius.
                case "C":
                case "G":
                    return this.Celsius.ToString("N2", provider) + "°C";
                default:
                    throw new FormatException(String.Format("The '{0}' format string is not supported.", format));
            }
        }
    }
Public Class Temperature : Implements IFormattable
    Private m_Temp As Decimal

    Public Sub New(temperature As Decimal)
        Me.m_Temp = temperature
    End Sub

    Public ReadOnly Property Celsius() As Decimal
        Get
            Return Me.m_Temp
        End Get
    End Property

    Public ReadOnly Property Kelvin() As Decimal
        Get
            Return Me.m_Temp + 273.15D
        End Get
    End Property

    Public ReadOnly Property Fahrenheit() As Decimal
        Get
            Return Math.Round(CDec(Me.m_Temp * 9 / 5 + 32), 2)
        End Get
    End Property

    Public Overrides Function ToString() As String
        Return Me.ToString("G", Nothing)
    End Function

    Public Overloads Function ToString(format As String) As String
        Return Me.ToString(format, Nothing)
    End Function

    Public Overloads Function ToString(format As String, provider As IFormatProvider) As String _
       Implements IFormattable.ToString

        ' Handle null or empty arguments.
        If String.IsNullOrEmpty(format) Then format = "G"
        ' Remove any white space and convert to uppercase.
        format = format.Trim().ToUpperInvariant()

        If provider Is Nothing Then provider = NumberFormatInfo.CurrentInfo

        Select Case format
     ' Convert temperature to Fahrenheit and return string.
            Case "F"
                Return Me.Fahrenheit.ToString("N2", provider) & "°F"
     ' Convert temperature to Kelvin and return string.
            Case "K"
                Return Me.Kelvin.ToString("N2", provider) & "K"
     ' Return temperature in Celsius.
            Case "C", "G"
                Return Me.Celsius.ToString("N2", provider) & "°C"
            Case Else
                Throw New FormatException(String.Format($"The '{format}' format string is not supported."))
        End Select
    End Function
End Class

Poniższy przykład tworzy wystąpienie Temperature obiektu. Następnie wywołuje metodę ToString i używa kilku ciągów formatu złożonego Temperature , aby uzyskać różne reprezentacje ciągów obiektu. Każda z tych metod wywołuje z kolei implementację IFormattableTemperature klasy .

public class Example11
{
    public static void Main()
    {
        CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
        Temperature temp = new Temperature(22m);
        Console.WriteLine(Convert.ToString(temp, new CultureInfo("ja-JP")));
        Console.WriteLine("Temperature: {0:K}", temp);
        Console.WriteLine("Temperature: {0:F}", temp);
        Console.WriteLine(String.Format(new CultureInfo("fr-FR"), "Temperature: {0:F}", temp));
    }
}
// The example displays the following output:
//       22.00°C
//       Temperature: 295.15K
//       Temperature: 71.60°F
//       Temperature: 71,60°F
Public Module Example12
    Public Sub Main12()
        Dim temp As New Temperature(22D)
        CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("en-US")
        Console.WriteLine(Convert.ToString(temp, New CultureInfo("ja-JP")))
        Console.WriteLine($"Temperature: {temp:K}")
        Console.WriteLine($"Temperature: {temp:F}")
        Console.WriteLine(String.Format(New CultureInfo("fr-FR"), $"Temperature: {temp:F}"))
    End Sub
End Module
' The example displays the following output:
'       22.00°C
'       Temperature: 295.15K
'       Temperature: 71.60°F
'       Temperature: 71,60°F

Złożone formatowanie

Niektóre metody, takie jak String.Format i StringBuilder.AppendFormat, obsługują formatowanie złożone. Ciąg formatu złożonego to rodzaj szablonu, który zwraca pojedynczy ciąg zawierający ciąg reprezentujący zero, jeden lub więcej obiektów. Każdy obiekt jest reprezentowany w ciągu formatu złożonego przez indeksowany element formatu. Indeks elementu formatu odpowiada pozycji obiektu reprezentowanego na liście parametrów metody. Indeksy są oparte na zera. Na przykład w poniższym wywołaniu String.Format metody pierwszy element {0:D}formatu , jest zastępowany przez reprezentację thatDateciągu ; drugi element {1}formatu , jest zastępowany przez reprezentację item1ciągu ; a trzeci element {2:C2}formatu , jest zastępowany przez reprezentację item1.Valueciągu .

result = String.Format("On {0:d}, the inventory of {1} was worth {2:C2}.",
                       thatDate, item1, item1.Value);
Console.WriteLine(result);
// The example displays output like the following if run on a system
// whose current culture is en-US:
//       On 5/1/2009, the inventory of WidgetA was worth $107.44.
result = String.Format("On {0:d}, the inventory of {1} was worth {2:C2}.",
                       thatDate, item1, item1.Value)
Console.WriteLine(result)
' The example displays output like the following if run on a system
' whose current culture is en-US:
'       On 5/1/2009, the inventory of WidgetA was worth $107.44.

Oprócz zastępowania elementu formatu ciągiem reprezentującym odpowiedni obiekt, elementy formatu umożliwiają również sterowanie następującymi elementami:

  • Określony sposób, w jaki obiekt jest reprezentowany jako ciąg, jeśli obiekt implementuje IFormattable interfejs i obsługuje ciągi formatu. Można to zrobić, postępując zgodnie z indeksem elementu formatu z dwukropkiem : , a następnie prawidłowym ciągiem formatu. Poprzedni przykład zrobił to, formatując wartość daty z ciągiem formatu "d" (wzorzec daty krótkiej) (np {0:d}. ) i formatując wartość liczbową z ciągiem formatu "C2" (np {2:C2} . w celu reprezentowania liczby jako wartości waluty z dwiema ułamkowymi cyframi dziesiętnymi).

  • Szerokość pola zawierającego reprezentację ciągu obiektu oraz wyrównanie reprezentacji ciągu w tym polu. Można to zrobić, postępując zgodnie z indeksem elementu formatu z (przecinkiem , ) po szerokości pola. Ciąg jest wyrównany do prawej strony w polu, jeśli szerokość pola jest wartością dodatnią i jest wyrównana do lewej, jeśli szerokość pola jest wartością ujemną. W poniższym przykładzie wartości daty w lewo są wyrównane w polu 20 znaków, a wartości dziesiętne są wyrównane do prawej z jedną cyfrą ułamkową w polu 11 znaków.

    DateTime startDate = new DateTime(2015, 8, 28, 6, 0, 0);
    decimal[] temps = { 73.452m, 68.98m, 72.6m, 69.24563m,
                       74.1m, 72.156m, 72.228m };
    Console.WriteLine("{0,-20} {1,11}\n", "Date", "Temperature");
    for (int ctr = 0; ctr < temps.Length; ctr++)
       Console.WriteLine("{0,-20:g} {1,11:N1}", startDate.AddDays(ctr), temps[ctr]);
    
    // The example displays the following output:
    //       Date                 Temperature
    //
    //       8/28/2015 6:00 AM           73.5
    //       8/29/2015 6:00 AM           69.0
    //       8/30/2015 6:00 AM           72.6
    //       8/31/2015 6:00 AM           69.2
    //       9/1/2015 6:00 AM            74.1
    //       9/2/2015 6:00 AM            72.2
    //       9/3/2015 6:00 AM            72.2
    
    Dim startDate As New Date(2015, 8, 28, 6, 0, 0)
    Dim temps() As Decimal = {73.452, 68.98, 72.6, 69.24563,
                               74.1, 72.156, 72.228}
    Console.WriteLine("{0,-20} {1,11}", "Date", "Temperature")
    Console.WriteLine()
    For ctr As Integer = 0 To temps.Length - 1
        Console.WriteLine("{0,-20:g} {1,11:N1}", startDate.AddDays(ctr), temps(ctr))
    Next
    ' The example displays the following output:
    '       Date                 Temperature
    '
    '       8/28/2015 6:00 AM           73.5
    '       8/29/2015 6:00 AM           69.0
    '       8/30/2015 6:00 AM           72.6
    '       8/31/2015 6:00 AM           69.2
    '       9/1/2015 6:00 AM            74.1
    '       9/2/2015 6:00 AM            72.2
    '       9/3/2015 6:00 AM            72.2
    

    Należy pamiętać, że jeśli zarówno składnik ciągu wyrównania, jak i składnik ciągu formatu są obecne, poprzedni poprzedza ten ostatni (na przykład {0,-20:g}.

Aby uzyskać więcej informacji na temat formatowania złożonego, zobacz Formatowanie złożone.

Formatowanie niestandardowe za pomocą klasy ICustomFormatter

Dwie metody formatowania złożonego i String.Format(IFormatProvider, String, Object[])StringBuilder.AppendFormat(IFormatProvider, String, Object[]), zawierają parametr dostawcy formatu, który obsługuje formatowanie niestandardowe. Po wywołaniu jednej z tych metod formatowania przekazuje Type obiekt reprezentujący ICustomFormatter interfejs do metody dostawcy GetFormat formatu. Metoda GetFormat jest następnie odpowiedzialna za zwrócenie implementacji ICustomFormatter , która zapewnia niestandardowe formatowanie.

Interfejs ICustomFormatter ma jedną metodę , Format(String, Object, IFormatProvider)która jest wywoływana automatycznie przez metodę formatowania złożonego, raz dla każdego elementu formatu w ciągu formatu złożonego. Metoda Format(String, Object, IFormatProvider) ma trzy parametry: ciąg formatu, który reprezentuje formatString argument w elemencie formatu, obiekt do sformatowania i IFormatProvider obiekt, który zapewnia usługi formatowania. Zazwyczaj klasa implementująca również implementuje ICustomFormatterIFormatProviderelement , więc ten ostatni parametr jest odwołaniem do niestandardowej klasy formatowania. Metoda zwraca niestandardową sformatowaną reprezentację ciągu obiektu do sformatowania. Jeśli metoda nie może sformatować obiektu, powinna zwrócić odwołanie o wartości null (Nothing w Visual Basic).

W poniższym przykładzie przedstawiono implementację ICustomFormatter o nazwie ByteByByteFormatter , która wyświetla wartości całkowite jako sekwencję dwucyfrowych wartości szesnastkowe, po których następuje spacja.

public class ByteByByteFormatter : 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 (! formatProvider.Equals(this)) return null;

      // Handle only hexadecimal format string.
      if (! format.StartsWith("X")) return null;

      byte[] bytes;
      string output = null;

      // Handle only integral types.
      if (arg is Byte)
         bytes = BitConverter.GetBytes((Byte) arg);
      else if (arg is Int16)
         bytes = BitConverter.GetBytes((Int16) arg);
      else if (arg is Int32)
         bytes = BitConverter.GetBytes((Int32) arg);
      else if (arg is Int64)
         bytes = BitConverter.GetBytes((Int64) arg);
      else if (arg is SByte)
         bytes = BitConverter.GetBytes((SByte) arg);
      else if (arg is UInt16)
         bytes = BitConverter.GetBytes((UInt16) arg);
      else if (arg is UInt32)
         bytes = BitConverter.GetBytes((UInt32) arg);
      else if (arg is UInt64)
         bytes = BitConverter.GetBytes((UInt64) arg);
      else
         return null;

      for (int ctr = bytes.Length - 1; ctr >= 0; ctr--)
         output += String.Format("{0:X2} ", bytes[ctr]);

      return output.Trim();
   }
}
Public Class ByteByByteFormatter : 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, arg As Object,
                           formatProvider As IFormatProvider) As String _
                           Implements ICustomFormatter.Format

        If Not formatProvider.Equals(Me) Then Return Nothing

        ' Handle only hexadecimal format string.
        If Not fmt.StartsWith("X") Then
            Return Nothing
        End If

        ' Handle only integral types.
        If Not typeof arg Is Byte AndAlso
           Not typeof arg Is Int16 AndAlso
           Not typeof arg Is Int32 AndAlso
           Not typeof arg Is Int64 AndAlso
           Not typeof arg Is SByte AndAlso
           Not typeof arg Is UInt16 AndAlso
           Not typeof arg Is UInt32 AndAlso
           Not typeof arg Is UInt64 Then _
              Return Nothing

        Dim bytes() As Byte = BitConverter.GetBytes(arg)
        Dim output As String = Nothing

        For ctr As Integer = bytes.Length - 1 To 0 Step -1
            output += String.Format("{0:X2} ", bytes(ctr))
        Next

        Return output.Trim()
    End Function
End Class

W poniższym przykładzie użyto ByteByByteFormatter klasy do formatowania wartości całkowitych. Należy pamiętać, że ICustomFormatter.Format metoda jest wywoływana więcej niż raz w drugim String.Format(IFormatProvider, String, Object[]) wywołaniu metody i że dostawca domyślny NumberFormatInfo jest używany w trzecim wywołaniu metody, ponieważ .ByteByByteFormatter.Format metoda nie rozpoznaje ciągu formatu "N0" i zwraca odwołanie o wartości null (Nothing w Visual Basic).

public class Example10
{
   public static void Main()
   {
      long value = 3210662321;
      byte value1 = 214;
      byte value2 = 19;

      Console.WriteLine(String.Format(new ByteByByteFormatter(), "{0:X}", value));
      Console.WriteLine(String.Format(new ByteByByteFormatter(), "{0:X} And {1:X} = {2:X} ({2:000})",
                                      value1, value2, value1 & value2));
      Console.WriteLine(String.Format(new ByteByByteFormatter(), "{0,10:N0}", value));
   }
}
// The example displays the following output:
//       00 00 00 00 BF 5E D1 B1
//       00 D6 And 00 13 = 00 12 (018)
//       3,210,662,321
Public Module Example10
    Public Sub Main10()
        Dim value As Long = 3210662321
        Dim value1 As Byte = 214
        Dim value2 As Byte = 19

        Console.WriteLine((String.Format(New ByteByByteFormatter(), "{0:X}", value)))
        Console.WriteLine((String.Format(New ByteByByteFormatter(), "{0:X} And {1:X} = {2:X} ({2:000})",
                                        value1, value2, value1 And value2)))
        Console.WriteLine(String.Format(New ByteByByteFormatter(), "{0,10:N0}", value))
    End Sub
End Module
' The example displays the following output:
'       00 00 00 00 BF 5E D1 B1
'       00 D6 And 00 13 = 00 12 (018)
'       3,210,662,321

Zobacz też

Tytuł Definicja
Standardowe ciągi formatów liczbowych Opisuje standardowe ciągi formatu, które tworzą powszechnie używane reprezentacje ciągów wartości liczbowych.
Niestandardowe ciągi formatujące liczby Opisuje niestandardowe ciągi formatu, które tworzą formaty specyficzne dla aplikacji dla wartości liczbowych.
Standardowe ciągi formatu data i godzina Opisuje standardowe ciągi formatu, które tworzą powszechnie używane reprezentacje ciągów DateTime wartości.
Niestandardowe ciągi formatu data i godzina Opisuje niestandardowe ciągi formatu, które tworzą formaty specyficzne dla aplikacji dla DateTime wartości.
Standardowe ciągi formatujące TimeSpan Opisuje standardowe ciągi formatu, które tworzą powszechnie używane reprezentacje ciągów interwałów czasu.
Niestandardowe ciągi formatujące TimeSpan Opisuje niestandardowe ciągi formatu, które tworzą formaty specyficzne dla aplikacji dla interwałów czasu.
Ciągi formatujące wyliczenia Opisuje standardowe ciągi formatu używane do tworzenia reprezentacji ciągów wartości wyliczenia.
Złożone formatowanie Opisuje sposób osadzania co najmniej jednej sformatowanej wartości w ciągu. Ciąg można następnie wyświetlić w konsoli lub zapisać w strumieniu.
Analizowanie ciągów Opisuje sposób inicjowania obiektów do wartości opisanych przez reprezentacje ciągów tych obiektów. Analizowanie to odwrotna operacja formatowania.

Odwołanie