Typy formátování
Formátování je proces převodu instance třídy, struktury nebo výčtové hodnoty na řetězcové vyjádření, často tak, aby mohl být výsledný řetězec zobrazen uživatelům nebo rekonstruován pro obnovení původního datového typu. Tento převod může představovat určitá úskalí:
Způsob interního uložení hodnoty nutně neodráží způsob, kterým ho chtějí uživatelé zobrazit. Například telefonní číslo může být uloženo ve formě 8009999999, která není srozumitelná. Namísto toho má být zobrazeno jako 800-999-9999.
Někdy není převod objektu na svou řetězcovou reprezentaci intuitivní. Například není zřejmé, jak by měla být zobrazena řetězcová reprezentace objektu teplota nebo osoba.
Hodnoty často vyžadují specifické formátování pro danou jazykovou verzi. Například v aplikaci, která používá čísla pro zobrazení peněžních hodnot, by měly číselné řetězce obsahovat symbol měny aktuální jazykové verze, oddělovač skupin (který je u většiny verzí oddělovač tisíců) a desetinný oddělovač.
Po aplikaci může být požadováno zobrazení stejné hodnoty různými způsoby. Například může aplikace vyjadřovat člen výčtového typu zobrazením řetězcové reprezentace jeho názvu nebo zobrazením jeho zadané hodnoty.
Poznámka |
---|
Formátování převede hodnotu typu na řetězcovou reprezentaci.Analýza je k formátování inverzní.Operace analýzy vytváří instanci datového typu z jeho řetězcové reprezentace.Informace o převedení řetězce na jiné datové typy naleznete v tématu Analýza řetězců. |
Rozhraní .NET Framework poskytuje bohatou podporu formátování, která umožňuje vývojářům tyto požadavky splnit.
Tento přehled obsahuje následující oddíly:
Formátování v rozhraní .NET Framework
Výchozí formátování pomocí metody ToString
Přetížení metody ToString
Metoda ToString a formátovací řetězce
Poskytovatelé formátu a rozhraní IFormatProvider
Rozhraní IFormattable
Složené formátování
Vlastní formátování pomocí ICustomFormatter
Příbuzná témata
Odkaz
Formátování v rozhraní .NET Framework
Základní mechanismus pro formátování je výchozí implementace metody Object.ToString, který je popsán v oddílu Výchozí formátování pomocí metody ToString dále v tomto tématu. Rozhraní .NET Framework však nabízí několik způsobů, jak upravit a rozšířit její výchozí podporu formátování. Například:
Přetížení metody Object.ToString pro definování vlastní řetězcové reprezentace hodnoty objektu. Další informace naleznete dále v tomto tématu v oddílu Přetížení metody ToString.
Definování specifikátorů formátu pro umožnění toho, aby daná řetězcová reprezentace hodnoty objektu mohla mít více tvarů. Například specifikátor formátu "X" v následujícímu příkazu převede celé číslo na řetězcovou reprezentaci šestnáctkové hodnoty.
Console.WriteLine(integerValue.ToString("X")) ' Displays EB98.
Console.WriteLine(integerValue.ToString("X")); // Displays EB98.
Další informace o specifikátorech formátu naleznete v oddíle Metoda ToString a formátovací řetězce.
Použití poskytovatelů formátu pro využití výhod konvencí formátování specifické jazykové verze. Následující příkaz například zobrazí hodnotu měny pomocí konvencí formátování jazykové verze en-US.
Console.WriteLine(cost.ToString("C", New System.Globalization.CultureInfo("en-US"))) ' The example displays the following output: ' $1,632.54
Console.WriteLine(cost.ToString("C", new System.Globalization.CultureInfo("en-US"))); // The example displays the following output: // $1,632.54
Další informace o formátování pomocí poskytovatelů formátu naleznete v oddílu Poskytovatelé formátu a rozhraní IFormatProvider.
Implementování rozhraní IFormattable pro podporu, jak převodu řetězce pomocí třídy Convert, tak složeného formátování. Další informace naleznete v oddílu Rozhraní IFormattable.
Použití složeného formátování pro vložení řetězcové reprezentace hodnoty do většího řetězce. Další informace naleznete v oddílu Složené formátování.
Implementování ICustomFormatter a IFormatProvider pro poskytnutí kompletního vlastního řešení formátování. Další informace naleznete v oddílu Vlastní formátování pomocí ICustomFormatter.
V následujících oddílech jsou tyto metody pro převod objektu na řetězcovou reprezentaci probrány.
Zpět na začátek
Výchozí formátování pomocí metody ToString
Každý typ, který je odvozen z System.Object automaticky dědí metodu ToString bez parametrů, která ve výchozím nastavení vrátí název typu. Následující příklad ukazuje takovouto výchozí metodu ToString. Je definována třída s názvem Automobile, která nemá žádnou implementaci. Když je vytvořena instance třídy a je zavolána její metoda ToString, zobrazí se název jejího typu.
Public Class Automobile
' No implementation. All members are inherited from Object.
End Class
Module Example
Public Sub Main()
Dim firstAuto As New Automobile()
Console.WriteLine(firstAuto)
End Sub
End Module
' The example displays the following output:
' Automobile
using System;
public class Automobile
{
// No implementation. All members are inherited from Object.
}
public class Example
{
public static void Main()
{
Automobile firstAuto = new Automobile();
Console.WriteLine(firstAuto);
}
}
// The example displays the following output:
// Automobile
Protože všechny typy jiné než rozhraní jsou odvozeny z Object, tato funkce je automaticky poskytnuta vlastním třídám nebo strukturám. Funkcionalita nabízená výchozí metodou ToString je však omezena: Přestože identifikuje typ, dojde k chybě při poskytování jakýchkoli informací o instanci typu. Chcete-li poskytnout řetězcovou reprezentaci objektu, který obsahuje informace o tomto objektu, musíte přetížit metodu ToString.
Poznámka |
---|
Struktury dědí z ValueType, který je zase odvozen z Object.Přestože ValueType přetěžuje Object.ToString, jejich implementace jsou totožné. |
Zpět na začátek
Přetížení metody ToString
Zobrazení názvu typu má často omezené použití a neumožňuje odběratelům vašich typů rozlišit jednu instanci od druhé. Můžete však přetížit metodu ToString pro poskytnutí užitečnější reprezentace hodnoty objektu. V následujícím příkladu je definován objekt Temperature a je přetížena metoda ToString pro zobrazení teploty ve stupních Celsia.
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 Example
Public Sub Main()
Dim currentTemperature As New Temperature(23.6d)
Console.WriteLine("The current temperature is {0}.", currentTemperature)
End Sub
End Module
' The example displays the following output:
' The current temperature is 23.6°C.
using System;
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 Example
{
public static void Main()
{
Temperature currentTemperature = new Temperature(23.6m);
Console.WriteLine("The current temperature is {0}.", currentTemperature);
}
}
// The example displays the following output:
// The current temperature is 23.6°C.
V rozhraní .NET Framework byla metoda ToString každého primitivního hodnotového typu přetížena, aby vracela hodnotu objektu namísto jeho názvu. V následující tabulce jsou uvedeny přetížení pro každý primitivní typ. Povšimněte si, že většina přetěžovaných metod volá jiné přetížení metody ToString a předává jí specifikátor formátu "G" určující obecný formát pro daný typ a objekt IFormatProvider, který představuje aktuální jazykovou verzi.
Typ |
přetížení metody ToString |
---|---|
Vrátí buď Boolean.TrueString nebo Boolean.FalseString. |
|
Volání Byte.ToString("G", NumberFormatInfo.CurrentInfo) formátování Byte hodnota pro aktuální kultury. |
|
Vrátí znak jako řetězec. |
|
Volá DateTime.ToString("G", DatetimeFormatInfo.CurrentInfo) pro zformátování hodnoty data a času pro aktuální jazykovou verze. |
|
Volání Decimal.ToString("G", NumberFormatInfo.CurrentInfo) formátování Decimal hodnota pro aktuální kultury. |
|
Volání Double.ToString("G", NumberFormatInfo.CurrentInfo) formátování Double hodnota pro aktuální kultury. |
|
Volání Int16.ToString("G", NumberFormatInfo.CurrentInfo) formátování Int16 hodnota pro aktuální kultury. |
|
Volání Int32.ToString("G", NumberFormatInfo.CurrentInfo) formátování Int32 hodnota pro aktuální kultury. |
|
Volání Int64.ToString("G", NumberFormatInfo.CurrentInfo) formátování Int64 hodnota pro aktuální kultury. |
|
Volání SByte.ToString("G", NumberFormatInfo.CurrentInfo) formátování SByte hodnota pro aktuální kultury. |
|
Volání Single.ToString("G", NumberFormatInfo.CurrentInfo) formátování Single hodnota pro aktuální kultury. |
|
Volání UInt16.ToString("G", NumberFormatInfo.CurrentInfo) formátování UInt16 hodnota pro aktuální kultury. |
|
Volání UInt32.ToString("G", NumberFormatInfo.CurrentInfo) formátování UInt32 hodnota pro aktuální kultury. |
|
Volání UInt64.ToString("G", NumberFormatInfo.CurrentInfo) formátování UInt64 hodnota pro aktuální kultury. |
Zpět na začátek
Metoda ToString a formátovací řetězce
Spoléhání se na výchozí metodu ToString nebo na přetížení ToString je vhodné v případě, kdy má objekt jedinou řetězcovou reprezentaci. Hodnota objektu má však často více reprezentací. Například teploty lze vyjádřit v stupňů Fahrenheita, v kelvinech nebo stupňů Celsia. Podobně i celočíselná hodnota může být reprezentována mnoha způsoby, včetně 10, 10.0, 1.0e01 nebo 10,00 USD.
Pro umožnění více řetězcových reprezentací pro jednu hodnotu používá rozhraní .NET Framework formátovací řetězce. Formátovací řetězec je řetězec, který obsahuje jeden nebo více předdefinovaných specifikátorů formátu, což jsou jednotlivé znaky nebo skupiny znaků, které definují způsob, jak má metoda ToString formátovat svůj výstup. Formátovací řetězec je pak předán jako parametr metodě ToString daného objektu a určuje, jak se má řetězcová reprezentace hodnoty tohoto objektu zobrazit.
Všechny číselné typy, typy data a času a typy výčtu v rozhraní .NET Framework podporují předdefinovanou sadu specifikátorů formátu. Formátovací řetězce můžete také použít pro definování více řetězcových reprezentací datových typů definovaných vaší aplikací.
Standardní formátovací řetězce
Standardní formátovací řetězec obsahuje jediný specifikátor formátu, což je znak abecedy, který definuje řetězcovou reprezentaci objektu, na který je uplatněna, spolu s volitelným specifikátorem přesnosti, který ovlivňuje počet číslic zobrazovaných ve výsledném řetězci. Pokud je specifikátor přesnosti vynechán nebo není podporován, standardní specifikátor formátu pak odpovídá standardnímu formátovacímu řetězci.
Rozhraní .NET Framework definuje sadu standardních specifikátorů formátu pro všechny číselné typy, všechny typy data a času a všechny typy výčtu. Každá z těchto kategorií například podporuje standardní specifikátor formátu "G", který definuje obecnou řetězcovou reprezentaci hodnoty daného typu.
Standardní formátovací řetězce pro výčtové typy přímo ovládají řetězcovou reprezentaci hodnoty. Formátovací řetězce předané metodě ToString výčtové hodnoty určují, zda je hodnota zobrazena pomocí jejího řetězcového názvu (specifikátory formátu "G" a "F"), její základní celočíselné hodnoty (specifikátor formátu "D") nebo její šestnáctkové hodnoty (specifikátor formátu "X"). Následující příklad ukazuje použití standardního formátovacího řetězce pro formátování výčtové hodnoty DayOfWeek.
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
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
Informace o formátovacích řetězcích výčtů naleznete v tématu Provádění výčtů formátovacích řetězců.
Standardní formátovací řetězce pro číselné typy obvykle definují výsledný řetězec, jehož přesný vzhled je řízen jednou nebo více vlastnostmi. Specifikátor formátu "C" například zformátuje číslo jako hodnotu měny. Při zavolání metody ToString se specifikátorem formátu "C" jako jediným parametrem, jsou použity pro definování řetězcové reprezentace číselné hodnoty tyto vlastnosti objektu NumberFormatInfo aktuální jazykové verze:
Vlastnost CurrencySymbol, která určuje symbol měny aktuální jazykové verze.
Vlastnost CurrencyNegativePattern nebo CurrencyPositivePattern vracející celé číslo, které určuje následující:
Umístění symbolu měny.
Zda jsou záporné hodnoty znázorněny se záporným znaménkem na počátku, na konci nebo pomocí závorek.
Zda se mezi číselnou hodnota a symbolem měny zobrazí mezera.
Vlastnost CurrencyDecimalDigits, která definuje počet zlomkových číslic ve výsledném řetězci.
Vlastnost CurrencyDecimalSeparator, která definuje symbol desetinného oddělovače ve výsledném řetězci.
Vlastnost CurrencyGroupSeparator, která definuje symbol oddělovače skupiny.
Vlastnost CurrencyGroupSizes, která definuje počet číslic v každé skupině číslic nalevo od desetinné čárky.
Vlastnost NegativeSign, která určuje záporné znaménko použité ve výsledném řetězci, pokud nejsou k označení záporné hodnoty použity závorky.
Kromě toho mohou formátovací řetězce čísel obsahovat specifikátor přesnosti. Význam tohoto specifikátoru závisí na použitém formátovacím řetězci, ale obvykle označuje buď celkový počet číslic nebo počet zlomkových číslic, které se mají zobrazit ve výsledném řetězci. V následujícím příkladu je například použit standardní číselný řetězec a specifikátor přesnosti "X4" pro vytvoření řetězcové hodnoty, která má čtyři šestnáctkové číslice.
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
byte[] byteValues = { 12, 163, 255 };
foreach (byte byteValue in byteValues)
Console.WriteLine(byteValue.ToString("X4"));
// The example displays the following output:
// 000C
// 00A3
// 00FF
Další informace o standardních číselných formátovacích řetězcích naleznete v tématu Standardní číselné formátovací řetězce.
Standardní formátovací řetězce pro hodnoty data a času jsou zástupci pro vlastní formátovací řetězce uložených určitou vlastností DateTimeFormatInfo. Například volání metody ToString hodnoty data a času se specifikátorem formátu "D", zobrazí datum a čas pomocí vlastního formátovacího řetězce, který je uložen ve vlastnosti DateTimeFormatInfo.LongDatePattern aktuální jazykové verze. (Další informace o vlastních formátovacích řetězcích naleznete v dalším oddílu.) Následující příklad ukazuje tuto vazbu.
Imports System.Globalization
Module Example
Public Sub Main()
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
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
Další informace o standardních formátovacích řetězcích data a času naleznete v tématu Standardní formátovací řetězce data a času.
Standardní formátovací řetězce můžete také použít pro definování řetězcové reprezentace objektu definovaného aplikací, který je vytvořen metodou ToString(String) daného objektu. Můžete definovat určité standardní specifikátory formátu, které jsou podporovány vašim objektem a můžete určit, zda rozlišují nebo nerozlišují velká a malá písmena. Vaše implementace metody ToString(String) by měla podporovat následující:
Specifikátor formátu "G" představující obvyklý nebo obecný formát objektu. Přetížení metody ToString vašeho objektu bez parametrů by mělo volat přetížení ToString(String) a předat standardní formátovací řetězec "G".
Podporu specifikátoru formátu, který je roven nulovému odkazu (Nothing v jazyce Visual Basic). Specifikátor formátu, který je roven nulovému odkazu by měl být považován za ekvivalent specifikátoru formátu "G".
Například Temperature třídy interně uložit teplota ve stupních Celsia a představují hodnotu pomocí specifikátorů formátu Temperature objektu ve stupních Celsia, stupňů Fahrenheita a kelvinech. Následující příklad uvádí ukázku.
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()
' Convert temperature to Fahrenheit and return string.
Select Case format
Case "F"
Return Me.Fahrenheit.ToString("N2") & " °F"
' Convert temperature to Kelvin and return string.
Case "K"
Return Me.Kelvin.ToString("N2") & " K"
' Return temperature in Celsius.
Case "C"
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 Example
Public Sub Main()
Dim temp1 As New Temperature(0d)
Console.WriteLine(temp1.ToString())
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("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("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
' 32.00 °F
' 273.15 K
' -40.00 °C
' -40.00 °C
' -40.00 °F
' 233.15 K
' 16.00 °C
' 16.00 °C
' 60.80 °F
' 289.15 K
' The temperature is now 16.00 °C.
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 "C":
return this.Celsius.ToString("N2") + " °C";
default:
throw new FormatException(String.Format("The '{0}' format string is not supported.", format));
}
}
}
public class Example
{
public static void Main()
{
Temperature temp1 = new Temperature(0m);
Console.WriteLine(temp1.ToString());
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("C"));
Console.WriteLine(temp2.ToString("F"));
Console.WriteLine(temp2.ToString("K"));
Temperature temp3 = new Temperature(16m);
Console.WriteLine(temp3.ToString());
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
// 32.00 °F
// 273.15 K
// -40.00 °C
// -40.00 °C
// -40.00 °F
// 233.15 K
// 16.00 °C
// 16.00 °C
// 60.80 °F
// 289.15 K
// The temperature is now 16.00 °C.
Zpět na začátek
Vlastní formátovací řetězce
Kromě standardních formátovacích řetězců definuje rozhraní .NET Framework vlastní formátovací řetězce pro číselné hodnoty a pro hodnoty data a času. Vlastní formátovací řetězec se skládá z jednoho nebo více vlastních specifikátorů formátu definující řetězcovou reprezentaci hodnoty. Například vlastní formátovací řetězec pro datum a čas "rrrr/mm/dd hh:mm:ss.ffff t zzz" převede datum na řetězcovou reprezentaci ve tvaru "2008/11/15 07:45:00.0000 P-08: 00" pro jazykovou verzi en-US. Podobně, vlastní formátovací řetězec "0000" převede celočíselnou hodnotu 12 na "0012". Kompletní seznam vlastních formátovacích řetězců naleznete v tématu Vlastní formátovací řetězce data a času a Vlastní číselné formátovací řetězce.
Pokud formátovací řetězec obsahuje jeden vlastní specifikátor formátu, měl by být tento specifikátor formátu uvozen symbolem procenta (%), aby nedocházelo k záměně se standardním specifikátorem formátu. V následujícím příkladu je použit vlastní specifikátor formátu "M" pro zobrazení jednociferného nebo dvojciferného čísla měsíce konkrétního data.
Dim date1 As Date = #09/08/2009#
Console.WriteLine(date1.ToString("%M")) ' Displays 9
DateTime date1 = new DateTime(2009, 9, 8);
Console.WriteLine(date1.ToString("%M")); // Displays 9
Mnoho standardních formátovacích řetězců pro hodnoty data a času jsou zástupci pro vlastní formátovací řetězce, které jsou definovány vlastnostmi objektu DateTimeFormatInfo. Vlastní formátovací řetězce také nabízejí značnou flexibilitu při poskytování formátování definovaného aplikací pro číselné hodnoty nebo pro hodnoty data a času. Kombinováním více vlastních specifikátorů formátu do jediného vlastního formátovacího řetězce můžete nadefinovat vlastní výsledný řetězec jak pro číselné hodnoty tak pro hodnoty data a času. V následujícím příkladu je definován vlastní formátovací řetězec, který zobrazuje den v týdnu v závorkách za názvem měsíce, dnem a rokem.
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)
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)
Ačkoli standardní formátovací řetězce mohou zpracovat většinu požadavků na formátování typů definovaných vaší aplikací, můžete také definovat vlastní specifikátory formátu pro formátování těchto typů.
Zpět na začátek
Poskytovatelé formátu a rozhraní IFormatProvider
I když specifikátory formátu umožňují přizpůsobit formátování objektů, vytváření smysluplné řetězcové reprezentace objektů často vyžaduje další informace o formátování. Například formátování čísla jako hodnoty měny pomocí standardního formátovacího řetězce "C" nebo vlastního formátovacího řetězce jako je "$ #,#.00" vyžaduje mít přinejmenším k dispozici informace o správném symbolu měny, oddělovači skupin a oddělovači desetinných míst, aby mohly být zahrnuty do formátovaného řetězce. V rozhraní .NET Framework jsou tyto dodatečné informace o formátování k dispozici pomocí rozhraní IFormatProvider, které je poskytnuto jako parametr pro jedno nebo více přetížení metody ToString číselného typy a typu data a času. Následující příklad ukazuje, jak se řetězcová reprezentace objektu změní, když je formátován pomocí tří různých objektů IFormatProvider.
Imports System.Globalization
Public Module Example
Public Sub Main()
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 €
using System;
using System.Globalization;
public class Example
{
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 €
Rozhraní IFormatProvider zahrnuje jednu metoda GetFormat(Type), která má jeden parametr určující typ objektu, který poskytuje informace o formátování. Pokud může metoda poskytnout objekt tohoto typu, vrátí jej. V opačném případě vrátí hodnotu nulového odkazu (Nothing v jazyce Visual Basic).
IFormatProvider.GetFormat je metoda zpětného volání. Při zavolání přetížení metody ToString obsahující parametr IFormatProvider, je volána metoda GetFormat objektu IFormatProvider. Metoda GetFormat je zodpovědná za vrácení objektu, který obsahuje nezbytné informace o formátování specifikované parametrem formatType metody ToString.
Několik metod pro formátování nebo převod řetězce obsahuje parametr typu IFormatProvider, ale v mnoha případech je při volání metody hodnota parametru ignorována. V následující tabulce jsou uvedeny některé metody formátování, které používají tento parametr a typ objektu Type, který předávají metodě IFormatProvider.GetFormat.
Metoda |
Typ parametru formatType |
---|---|
Metoda ToString pro numerické typy |
|
Metoda ToString pro typy data a času |
|
Poznámka |
---|
Metody ToString pro číselné typy a typy data a času jsou přetížené a pouze některé přetížení obsahují parametr IFormatProvider.Pokud metoda nemá parametr typu IFormatProvider, je místo něho předán objekt vrácený vlastností CultureInfo.CurrentCulture.Například volání výchozí metody Int32.ToString() nakonec vyústí ve volání metod jako je následující: Int32.ToString("G", System.Globalization.CultureInfo.CurrentCulture). |
Rozhraní .NET Framework poskytuje tři třídy, které implementují IFormatProvider:
Třída DateTimeFormatInfo, která poskytuje informace o formátování hodnot data a času pro určitou jazykovou verzi. Implementace IFormatProvider.GetFormat vrátí instanci sebe sama.
Třída NumberFormatInfo, která poskytuje informace o formátování čísel pro konkrétní jazykovou verzi. Implementace IFormatProvider.GetFormat vrátí instanci sebe sama.
CultureInfo. Implementace IFormatProvider.GetFormat může vrátit buď objekt NumberFormatInfo, který poskytuje informace o formátování čísel nebo objekt DateTimeFormatInfo, který poskytuje informace o formátování hodnot data a času.
Můžete také implementovat vlastní třídu poskytovatele formátu pro nahrazení kterékoli z těchto tříd. Implementace vaši metody GetFormat však musí vrátit objekt typu, který je uveden v předchozí tabulce, pokud má poskytovat informace o formátování metodě ToString.
Zpět na začátek
Rozhraní IFormattable
Obvykle typy, které přetěžují metodu ToString pomocí formátovacího řetězce a parametru IFormatProvider, také implementují rozhraní IFormattable. Toto rozhraní má jediný člen IFormattable.ToString(String, IFormatProvider), obsahující jak formátovací řetězec tak i poskytovatele formátu jako parametry.
Implementováním rozhraní IFormattable třídou definovanou vaší aplikací, nabízí dvě výhody:
Podpora převodu řetězce pomocí třídy Convert. Volání metod Convert.ToString(Object) a Convert.ToString(Object, IFormatProvider) volá automaticky vaši implementaci IFormattable.
Podpora pro složené formátování. Pokud položka formátu, která obsahuje formátovací řetězec, slouží k formátování vašeho vlastního typu, modul CLR (Common Language Runtime) automaticky volá vaši implementaci IFormattable a předává jí formátovací řetězec. Další informace o složeném formátování pomocí metod jako jsou String.Format nebo Console.WriteLine naleznete v oddílu Složené formátování.
V následujícím příkladu je definována třída Temperature, která implementuje rozhraní IFormattable. Podporuje specifikátory formátu "C" nebo "G" pro zobrazení teploty ve stupních Celsia, specifikátor formátu "F" pro zobrazení teploty ve stupních Fahrenheita a specifikátor formátu "K" pro zobrazení teploty ve stupních Kelvinů.
Imports System.Globalization
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 '{0}' format string is not supported.", format))
End Select
End Function
End Class
using System;
using System.Globalization;
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 convert 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));
}
}
}
V následujícím příkladu je vytvořena instance objektu Temperature. Potom je volána metoda ToString a je použito několik složených formátovacích řetězců pro získání různých řetězcových reprezentací objektu Temperature. Každé z těchto volání metod volá implementaci IFormattable třídy Temperature.
Public Module Example
Public Sub Main()
Dim temp1 As New Temperature(22d)
Console.WriteLine(Convert.ToString(temp1, New CultureInfo("ja-JP")))
Console.WriteLine("Temperature: {0:K}", temp1)
Console.WriteLine("Temperature: {0:F}", temp1)
Console.WriteLine(String.Format(New CultureInfo("fr-FR"), "Temperature: {0:F}", temp1))
End Sub
End Module
' The example displays the following output:
' 22.00°C
' Temperature: 295.15°K
' Temperature: 71.60°F
' Temperature: 71,60°F
public class Example
{
public static void Main()
{
Temperature temp1 = new Temperature(22m);
Console.WriteLine(Convert.ToString(temp1, new CultureInfo("ja-JP")));
Console.WriteLine("Temperature: {0:K}", temp1);
Console.WriteLine("Temperature: {0:F}", temp1);
Console.WriteLine(String.Format(new CultureInfo("fr-FR"), "Temperature: {0:F}", temp1));
}
}
// The example displays the following output:
// 22.00°C
// Temperature: 295.15°K
// Temperature: 71.60°F
// Temperature: 71,60°F
Zpět na začátek
Složené formátování
Některé metody, jako je například String.Format a StringBuilder.AppendFormat, podporují také složené formátování. Složený formátovací řetězec je druh šablony, která vrátí jediný řetězec, který zahrnuje řetězcové vyjádření žádného, jednoho nebo více objektů. Každý objekt je reprezentován ve složeném formátovacím řetězci indexovanou položkou formátu. Index položky formátu odpovídá pozici objektu, který představuje v seznamu parametrů metody. Indexy jsou počítány od nuly. Například v následujícím volání metody String.Format je první položka formátu {0:D} nahrazena řetězcovou reprezentací thatDate; druhá položka formátu {1} je nahrazena řetězcovou reprezentací item1; a třetí položka formátu {2:C2} je nahrazena řetězcovou reprezentací item1.Value.
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.
Další informace o složeném formátování naleznete v tématu Složené formátování.
Zpět na začátek
Vlastní formátování pomocí ICustomFormatter
Některé metody pro složené formátování, jako například String.Format(IFormatProvider, String, Object[]) a StringBuilder.AppendFormat(IFormatProvider, String, Object[]), zahrnují parametr poskytovatele formátu, který podporuje vlastní formátování. Když je zavolána metoda formátování, předá objekt Type, který představuje rozhraní ICustomFormatter metodě GetFormat poskytovatele formátu. Metoda GetFormat je pak zodpovědná za navrácení implementace ICustomFormatter, která poskytuje vlastní formátování.
Rozhraní ICustomFormatter obsahuje jedinou metodu Format(String, Object, IFormatProvider), která je volána automaticky metodou složeného formátování pro každou položku formátu ve složeném formátovacím řetězci. Metoda Format(String, Object, IFormatProvider) má tři parametry: formátovací řetězec, který představuje argument formatString v položce formátu, objekt pro zformátování a objekt IFormatProvider, který poskytuje služby formátování. Obvykle třída, která implementuje ICustomFormatter také implementuje IFormatProvider a proto je tento poslední parametr odkaz na danou třídu vlastního formátování. Metoda vrátí řetězcovou reprezentaci vlastního formátování objektu, který má být formátován. Pokud metoda nemůže objekt zformátovat, měl by být vrácen nulový odkaz (Nothing v jazyce Visual Basic).
Následující příklad uvádí implementaci ICustomFormatter s názvem ByteByByteFormatter zobrazující celočíselné hodnoty jako sekvenci dvouciferných šestnáctkových hodnot následovanou mezerou.
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
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();
}
}
V následujícím příkladu je třída ByteByByteFormatter použita pro formátování celočíselné hodnoty. Všimněte si, že metoda ICustomFormatter.Format je ve druhém volání metody String.Format(IFormatProvider, String, Object[]) volána více než jednou, a že výchozí poskytovatel NumberFormatInfo je použit ve třetím volání metody, protože metoda .ByteByByteFormatter.Formatnerozpozná formátovací řetězec "N0" a vrátí nulový odkaz (Nothing v jazyce Visual Basic).
Public Module Example
Public Sub Main()
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
public class Example
{
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
Zpět na začátek
Příbuzná témata
Title |
Definice |
---|---|
Popisuje standardní formátovací řetězce, které vytvářejí běžně používané řetězcové reprezentace číselných hodnot. |
|
Popisuje vlastní formátovací řetězce, které vytvářejí formáty číselných hodnot specifické pro danou aplikaci. |
|
Popisuje standardní formátovací řetězce, které vytvářejí běžně používané řetězcové reprezentace DateTime hodnot. |
|
Popisuje vlastní formátovací řetězce, které vytvářejí formáty DateTime hodnot specifické pro danou aplikaci. |
|
Popisuje standardní formátovací řetězce, které vytvářejí běžně používané řetězcové reprezentace časových intervalů. |
|
Popisuje vlastní formátovací řetězce, které vytvářejí formáty časových intervalů specifické pro danou aplikaci. |
|
Popisuje standardní formátovací řetězce, které slouží k vytvoření řetězcové reprezentace hodnot výčtu. |
|
Popisuje, jak vložit jednu nebo více formátovaných hodnot do řetězce. Řetězec lze následně zobrazit na konzolu nebo zapsat do datového proudu. |
|
Seznam témat, která poskytují podrobné pokyny pro provádění určitých operací formátování. |
|
Popisuje, jak inicializovat objekty s hodnotami popsanými řetězcovou interpretací těchto objektů. Analýza je inverzní operace k formátování. |
Zpět na začátek