概觀:如何在 .NET 中格式化數字、日期、列舉和其他型別
格式是將一個類別或結構的執行個體或列舉值轉換為字串表示法的處理程序。 目的是向使用者顯示產生的字串,或是在稍後進行還原序列化以還原原始的資料類型。 本文介紹 .NET 提供的格式化機制。
注意
剖析是格式化的反向操作。 剖析作業會從資料類型的字串表示來建立資料類型的執行個體。 如需詳細資訊,請參閱剖析字串。 如需序列化和還原序列化的詳細資訊,請參閱 .NET 中的序列化。
格式化機制的基礎在於 Object.ToString 方法的預設實作,這將於本主題稍後的使用 ToString 方法的預設格式一節中討論。 不過,.NET 提供幾種方式來修改和擴充其預設格式化支援。 其中包括下列各項:
覆寫 Object.ToString 方法可定義物件值的自訂字串表示法。 如需詳細資訊,請參閱本主題稍後的覆寫 ToString 方法一節。
定義格式規範,使物件值的字串表示法可以採用多種形式。 例如,下列陳述式中的 "X" 格式規範會將整數轉換為十六進位值的字串表示。
int integerValue = 60312; Console.WriteLine(integerValue.ToString("X")); // Displays EB98.
Dim integerValue As Integer = 60312 Console.WriteLine(integerValue.ToString("X")) ' Displays EB98.
如需格式規範的詳細資訊,請參閱 ToString 方法和格式字串 一節。
使用格式提供者可實作特定文化特性的格式慣例。 例如,下列陳述式會使用 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
如需使用格式提供者進行格式化的詳細資訊,請參閱格式提供者一節。
實作 IFormattable 介面,以同時支援使用 Convert 類別和複合格式來轉換字串。 如需詳細資訊,請參閱 IFormattable 介面 一節。
使用複合格式將值的字串表示嵌入更大的字串中。 如需詳細資訊,請參閱 複合格式 一節。
使用字串插補 (更易讀的語法) 可將值的字串表示法內嵌在較大的字串中。 如需詳細資訊,請參閱字串內插補點。
實作 ICustomFormatter 和 IFormatProvider 來提供完整的自訂格式解決方案。 如需詳細資訊,請參閱 使用 ICustomFormatter 的自訂格式 一節。
下列各節會討論這些將物件轉換為其字串表示的方法。
使用 ToString 方法的預設格式
每個衍生自 System.Object 的類型都會自動繼承無參數的 ToString
方法,這個方法預設會傳回類型的名稱。 下列範例示範預設的 ToString
方法。 範例中會定義一個不具任何實作的 Automobile
類別。 當具現化這個類別並呼叫其 ToString
方法時,會顯示這個類別的類型名稱。 請注意,在範例中不會明確呼叫 ToString
方法。 Console.WriteLine(Object) 方法會隱含呼叫本身所收到做為引數傳遞之物件的 ToString
方法。
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
警告
自 Windows 8.1 起,Windows 執行階段包含有 IStringable 介面。此介面只有一個方法 IStringable.ToString,可提供預設的格式化支援。 不過,不建議 Managed 類型實作 IStringable
介面。 如需詳細資訊,請參閱 Windows 執行階段 和 IStringable 介面。
因為除介面以外的所有其他類型都會衍生自 Object,所以您的自訂類別或結構會自動被賦予此功能。 不過,預設的 ToString
方法提供的功能有限:它雖然可以識別類型,但無法提供類型執行個體的任何資訊。 若要提供物件的字串表示來表達該物件的相關資訊,您必須覆寫 ToString
方法。
注意
結構會繼承自 ValueType,而後者又會衍生自 Object。 雖然 ValueType 會覆寫 Object.ToString,但實作方法是相同的。
覆寫 ToString 方法
顯示類型的名稱通常用途不大,亦無法讓您類型的使用者藉以區分不同的執行個體。 不過,您可以覆寫 ToString
方法,以更實用的方式表示物件值。 下列範例定義 Temperature
物件,並覆寫其 ToString
方法來顯示攝氏溫度。
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.
在 .NET 中,已覆寫每個基本實值類型的 ToString
方法來顯示物件的值,而非物件的名稱。 下表顯示各基本類型如何覆寫 ToString 方法。 請注意,大部分經過覆寫的方法都會呼叫 ToString
方法的另一個多載,並且將 "G" 格式規範 (此規範定義此類型的一般格式) 和 IFormatProvider 物件 (此物件表示目前文化特性) 傳遞至這個多載。
類型 | ToString 覆寫 |
---|---|
Boolean | 傳回 Boolean.TrueString 或 Boolean.FalseString。 |
Byte | 呼叫 Byte.ToString("G", NumberFormatInfo.CurrentInfo) ,以根據目前的文化特性來格式化 Byte 值。 |
Char | 以字串形式傳回字元。 |
DateTime | 呼叫 DateTime.ToString("G", DatetimeFormatInfo.CurrentInfo) ,以根據對目前的文化特性來格式化日期和時間值。 |
Decimal | 呼叫 Decimal.ToString("G", NumberFormatInfo.CurrentInfo) ,以根據目前的文化特性來格式化 Decimal 值。 |
Double | 呼叫 Double.ToString("G", NumberFormatInfo.CurrentInfo) ,以根據目前的文化特性來格式化 Double 值。 |
Int16 | 呼叫 Int16.ToString("G", NumberFormatInfo.CurrentInfo) ,以根據目前的文化特性來格式化 Int16 值。 |
Int32 | 呼叫 Int32.ToString("G", NumberFormatInfo.CurrentInfo) ,以根據目前的文化特性來格式化 Int32 值。 |
Int64 | 呼叫 Int64.ToString("G", NumberFormatInfo.CurrentInfo) ,以根據目前的文化特性來格式化 Int64 值。 |
SByte | 呼叫 SByte.ToString("G", NumberFormatInfo.CurrentInfo) ,以根據目前的文化特性來格式化 SByte 值。 |
Single | 呼叫 Single.ToString("G", NumberFormatInfo.CurrentInfo) ,以根據目前的文化特性來格式化 Single 值。 |
UInt16 | 呼叫 UInt16.ToString("G", NumberFormatInfo.CurrentInfo) ,以根據目前的文化特性來格式化 UInt16 值。 |
UInt32 | 呼叫 UInt32.ToString("G", NumberFormatInfo.CurrentInfo) ,以根據目前的文化特性來格式化 UInt32 值。 |
UInt64 | 呼叫 UInt64.ToString("G", NumberFormatInfo.CurrentInfo) ,以根據目前的文化特性來格式化 UInt64 值。 |
ToString 方法及格式字串
當物件只有單一字串表示時,使用預設 ToString
方法或覆寫 ToString
都沒有問題。 不過,物件的值通常有多種表示。 例如,溫度可以用華氏、攝氏或開氏溫度表示。 同樣地,整數值 10 可以用許多方式表示,包括 10、10.0、1.0e01 或 $10.00。
為了讓單一值可以具有多種字串表示,.NET 使用格式字串。 格式字串是包含一個或多個預先定義之格式規範的字串,這個字串是單一字元或一組字元,用於定義 ToString
方法應採用的輸出格式。 然後,格式字串會當做參數傳遞至物件的 ToString
方法,以決定如何呈現該物件的值的字串表示。
.NET 中所有的數值類型、日期和時間類型,以及列舉類型,都支援一組預先定義的格式規範。 您也可以利用格式字串定義多種字串表示給您應用程式中定義的資料類型。
標準格式字串
標準格式字串包含單一格式規範 (一個字母字元,定義套用此規範之物件的字串表示) 和選擇性的精確度規範 (這個規範影響結果字串中顯示的位數)。 如果省略或不支援精確度規範,則標準格式規範與標準格式字串無異。
.NET 定義一組適用於所有數值類型、所有日期和時間類型,以及所有列舉類型的標準格式規範。 例如,這些分類每個都支援 "G" 標準格式規範 (這個規範定義該類型之值的一般字串表示)。
列舉類型的標準格式字串直接控制了值的字串表示。 傳遞給列舉值的 ToString
方法,其格式字串決定該值是以其字串名稱 ("G" 和 "F" 格式規範)、以其基礎整數值 ("D" 格式規範),或是以其十六進位值 ("X" 格式規範) 顯示。 下列範例示範如何使用標準格式字串來格式化 DayOfWeek 列舉值。
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
如需列舉格式字串的相關資訊,請參閱 Enumeration Format Strings。
數值類型的標準格式字串定義出的結果字串之確切外觀通常是由一個或多個屬性值所控制。 例如,"C" 格式規範會將數字格式化為貨幣值。 當您將 "C" 格式規範做為唯一參數來呼叫 ToString
方法時,會使用目前文化特性 NumberFormatInfo 物件中的下列屬性值定義數值的字串表示法:
CurrencySymbol 屬性,指定目前文化特性的貨幣符號。
CurrencyNegativePattern 或 CurrencyPositivePattern 屬性,這個屬性傳回的整數會決定:
貨幣符號的位置。
負值是以開頭負號、結尾負號還是括號來表示。
數值和貨幣符號之間是否顯示一個空格。
CurrencyDecimalDigits 屬性,定義結果字串中的小數位數。
CurrencyDecimalSeparator 屬性,定義結果字串中的十進位分隔符號。
CurrencyGroupSeparator 屬性,定義群組分隔符號。
CurrencyGroupSizes 屬性,定義小數點左邊每個群組的位數。
NegativeSign 屬性,決定當不使用括號來表示負數時,要在結果字串中使用的負數值表示符號。
此外,數值格式字串也可以包含精確度規範。 這個規範的意義視搭配使用的格式字串而定,但通常是表示結果字串中應該顯示的總位數或小數位數。 例如,下列範例會使用 "X4" 標準數值字串和精確度規範,建立具有四個十六進位數字的字串值。
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
如需標準數值格式字串的詳細資訊,請參閱 Standard Numeric Format Strings。
日期和時間值的標準格式字串是特定 DateTimeFormatInfo 屬性所儲存之自訂格式字串的別名。 例如,以 "D" 格式規範呼叫日期和時間值的 ToString
方法,會使用目前文化特性 DateTimeFormatInfo.LongDatePattern 屬性中儲存的自訂格式字串顯示日期和時間。 (如需自訂格式字串的詳細資訊,請參閱下一節)。下列範例示範這種關聯性。
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
如需標準日期和時間格式字串的詳細資訊,請參閱 Standard Date and Time Format Strings。
對於應用程式定義的物件,您也可以使用標準格式字串定義由該物件的 ToString(String)
方法所產生的字串表示法。 您可以定義您的物件所支援的特定標準格式規範,並且決定這項規範是否區分大小寫。 您對 ToString(String)
方法的實作應該要能支援:
"G" 格式規範,表示物件的慣用或通用格式。 您物件的
ToString
方法的無參數多載應該要呼叫這個方法的ToString(String)
多載,並且將 "G" 標準格式字串傳遞給這個方法。支援等於 null 參考 (在 Visual Basic 中為
Nothing
) 的格式規範。 等於 null 參考的格式規範應該要視為相當於 "G" 格式規範。
例如, Temperature
類別可以在內部以攝氏儲存溫度,並透過格式規範以攝氏、華氏和開氏溫度來表示 Temperature
物件的值。 下列範例提供一個實例。
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.
自訂格式字串
除了標準格式字串,.NET 也為數值以及日期和時間值定義了自訂格式字串。 自訂格式字串由一個或多個自訂格式規範組成,這些規範定義了值的字串表示。 例如,自訂日期和時間格式字串 "yyyy/mm/dd hh:mm:ss.ffff t zzz" 會將日期轉換為其字串表示,以 en-US 文化特性而言為 "2008/11/15 07:45:00.0000 P -08:00" 形式。 同樣地,自訂格式字串 "0000" 會將整數值 12 轉換為 "0012"。 如需完整的自訂格式字串清單,請參閱 Custom Date and Time Format Strings 和 Custom Numeric Format Strings。
如果格式字串由單一自訂格式規範組成,則應該在格式規範前面加上百分比 (%) 符號,以避免與標準格式規範產生混淆。 下列範例會使用 "M" 自訂格式規範來顯示特定日期的一位數或兩位數月份。
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
日期和時間值的許多標準格式字串都是自訂格式字串 (這些自訂格式字串由 DateTimeFormatInfo 物件的屬性所定義) 的別名。 自訂格式字串也提供極大的彈性,來提供應用程式定義的數值或日期和時間值格式。 您可以將多個自訂格式規範結合成單一自訂格式字串,以自訂您的數值及日期和時間值結果字串。 下列範例定義的自訂格式字串,會在月份名稱、日期和年後面顯示加上括號的星期。
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)
下列範例會定義自訂格式字串,該字串會將 Int64 值顯示為標準的七位數美國電話號碼且包含其區碼。
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
雖然標準格式字串通常能夠為應用程式定義的類型解決大部分的格式需求,但您也可以定義自訂格式規範來格式化您的類型。
格式字串與 .NET 類型
所有數字類型 (也就是 Byte、Decimal、Double、Int16、Int32、Int64、SByte、Single、UInt16、UInt32、UInt64 和 BigInteger 類型),以及 DateTime、DateTimeOffset、TimeSpan、Guid 和所有列舉類型,都支援以格式字串進行格式化。 如需每個類型所支援特定格式字串的資訊,請參閱下列主題:
標題 | 定義 |
---|---|
標準數值格式字串 \(部分機器翻譯\) | 說明建立數值常用之字串表示的標準格式字串。 |
自訂數值格式字串 | 說明建立應用程式專屬數值格式的自訂格式字串。 |
標準日期和時間格式字串 | 說明建立 DateTime 和 DateTimeOffset 值之常用字串表示的標準格式字串。 |
自訂日期和時間格式字串 | 說明建立應用程式專屬 DateTime 和 DateTimeOffset 值格式的自訂格式字串。 |
標準 TimeSpan 格式字串 | 說明建立時間間隔之常用字串表示的標準格式字串。 |
自訂 TimeSpan 格式字串 | 說明建立應用程式專屬數值格式的自訂格式字串。 |
Enumeration Format Strings | 說明用來建立列舉值之字串表示的標準格式字串。 |
Guid.ToString(String) | 描述 Guid 值的標準格式字串。 |
使用格式提供者進行符合文化特性的格式化
雖然格式規範可讓您自訂物件的格式,但如果要為物件產生有意義的字串表示,您通常還需要其他格式設定資訊。 例如,如果要使用 "C" 標準格式字串或自訂格式字串 (例如 "$ #,#.00") 將數字格式化為貨幣值,您至少還需要有正確的貨幣符號、群組分隔符號和小數分隔符號的相關資訊。 在 .NET 中,這項額外的格式資訊是透過 IFormatProvider 介面取得,而這個介面會當做傳遞至數字類型以及日期和時間類型的 ToString
方法之一個或多個多載的參數來提供。 IFormatProvider 實作會在 .NET 中用來支援文化特性特定的格式。 下列範例將示範以代表不同文化特性的三個 IFormatProvider 物件進行格式化時,物件的字串表示會有什麼樣的變化。
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 €
IFormatProvider 介面包含一個 GetFormat(Type)方法,這個方法具有單一參數來指定可提供格式設定資訊之物件的類型。 如果這個方法可以提供該類型的物件,則會傳回該物件。 否則會傳回 null 參考 (在 Visual Basic 中為Nothing
)。
IFormatProvider.GetFormat 是一種回呼方法。 當您呼叫包含 ToString
參數的 IFormatProvider 方法多載時,這個多載會呼叫該 GetFormat 物件的 IFormatProvider 方法。 GetFormat 方法負責將提供必要格式設定資訊的物件 (由其 formatType
參數指定),傳回給 ToString
方法。
有幾個格式化或字串轉換方法都包含 IFormatProvider類型的參數,但通常呼叫方法時,會忽略這個參數的值。 下表列出一些使用這個參數的格式化方法,以及這些方法傳遞至 Type 方法的 IFormatProvider.GetFormat 物件的類型。
方法 | formatType 參數的類型 |
---|---|
數字類型的 ToString 方法 |
System.Globalization.NumberFormatInfo |
日期和時間類型的 ToString 方法 |
System.Globalization.DateTimeFormatInfo |
String.Format | System.ICustomFormatter |
StringBuilder.AppendFormat | System.ICustomFormatter |
注意
數字類型及日期和時間類型的 ToString
方法都含有多載,而其中只有某些多載會包含 IFormatProvider 參數。 如果方法沒有 IFormatProvider類型的參數,則會改以傳遞 CultureInfo.CurrentCulture 屬性所傳回的物件。 例如,呼叫預設的 Int32.ToString() 方法最終會產生如下的方法呼叫: Int32.ToString("G", System.Globalization.CultureInfo.CurrentCulture)
。
.NET 提供三個實作 IFormatProvider 的類別:
DateTimeFormatInfo,這個類別提供特定文化特性之日期和時間值的格式設定資訊。 它的 IFormatProvider.GetFormat 實作會傳回它自己的執行個體。
NumberFormatInfo,這個類別提供特定文化特性的數值格式設定資訊。 它的 IFormatProvider.GetFormat 實作會傳回它自己的執行個體。
CultureInfo. 它的 IFormatProvider.GetFormat 實作可以傳回 NumberFormatInfo 物件來提供數值格式設定資訊,或傳回 DateTimeFormatInfo 物件來提供日期和時間值的格式設定資訊。
您也可以實作自己的格式提供者來取代上述任何一個類別。 不過,您實作的 GetFormat 方法如果必須提供格式資訊給 ToString
方法,則必須傳回上表所列型別的物件。
區分文化特性的數值格式
根據預設,數值格式會區分文化特性。 如果您呼叫格式化方法時未指定文化特性,則會使用目前文化特性所用的格式慣例。 下列範例將說明這種情形,其中文化特性會變更四次,然後呼叫 Decimal.ToString(String) 方法。 在各案例中,結果字串都會反映目前文化特性的格式設定慣例。 這是因為 ToString
和 ToString(String)
方法會包裝對每個數值類型之 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 €
您也可以呼叫具有 ToString
參數的 provider
多載並且將下列任一項傳遞給它,藉此格式化特定文化特性的數值:
CultureInfo 物件,表示要使用其格式設定慣例的文化特性。 它的 CultureInfo.GetFormat 方法會傳回 CultureInfo.NumberFormat 屬性的值,也就是為數值提供文化特性特有格式資訊的 NumberFormatInfo 物件。
NumberFormatInfo 物件,該物件會定義要使用的文化特性特有格式設定慣例。 它的 GetFormat 方法會傳回本身的執行個體。
下列範例將使用表示英文 (美國) 和英文 (英國) 文化特性以及法文和俄文中性文化特性的 NumberFormatInfo 物件,格式化浮點數。
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
區分文化特性格式的日期與時間值
根據預設,日期和時間值的格式區分文化特性。 如果您呼叫格式化方法時未指定文化特性,則會使用目前文化特性所用的格式慣例。 下列範例將說明這種情形,其中文化特性會變更四次,然後呼叫 DateTime.ToString(String) 方法。 在各案例中,結果字串都會反映目前文化特性的格式設定慣例。 這是因為 DateTime.ToString()、 DateTime.ToString(String)、 DateTimeOffset.ToString()和 DateTimeOffset.ToString(String) 方法會包裝 DateTime.ToString(String, IFormatProvider) 和 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
您也可以呼叫具有 DateTime.ToString 參數的 DateTimeOffset.ToString 或 provider
多載並且將下列任一項傳遞給它,藉此格式化特定文化特性的日期和時間值:
CultureInfo 物件,表示要使用其格式設定慣例的文化特性。 它的 CultureInfo.GetFormat 方法會傳回 CultureInfo.DateTimeFormat 屬性的值,也就是為日期和時間值提供文化特性特有格式資訊的 DateTimeFormatInfo 物件。
DateTimeFormatInfo 物件,該物件會定義要使用的文化特性特有格式設定慣例。 它的 GetFormat 方法會傳回本身的執行個體。
下列範例使用表示英文 (美國) 和英文 (英國) 文化特性以及法文和俄文中性文化特性的 DateTimeFormatInfo 物件,格式化浮點數。
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
IFormattable 介面
以格式字串和 ToString
參數來多載 IFormatProvider 方法的類型,通常也會實作 IFormattable 介面。 這個介面具有單一成員 IFormattable.ToString(String, IFormatProvider),這個成員同時包含格式字串和格式提供者做為參數。
針對您的應用程式定義的類別來實作 IFormattable 介面有兩項好處:
支援透過 Convert 類別來轉換字串。 呼叫 Convert.ToString(Object) 和 Convert.ToString(Object, IFormatProvider) 方法時,會自動呼叫您的 IFormattable 實作。
支援複合格式。 如果使用包含格式字串的格式項目來格式化您的自訂類型,則 Common Language Runtime 會自動呼叫您的 IFormattable 實作並將格式字串傳遞給這個實作。 如需透過 String.Format 或 Console.WriteLine等方法執行複合格式的詳細資訊,請參閱 複合格式 一節。
下列範例定義一個實作 Temperature
介面的 IFormattable 類別。 這個類別支援 "C" 或 "G" 格式規範來顯示攝氏溫度、支援 "F" 格式規範來顯示華氏溫度,也支援 "K" 格式規範來顯示絕對溫度。
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
下列範例會執行個體化 Temperature
物件。 然後呼叫 ToString 方法,並使用數個複合格式字串來取得 Temperature
物件的不同字串表示。 其中每個方法又呼叫 IFormattable 類別的 Temperature
實作。
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
複合格式
某些方法 (例如 String.Format 和 StringBuilder.AppendFormat) 支援複合格式。 複合格式字串是一種範本,可傳回由零個、一個或更多物件的字串表示所組成的單一字串。 複合格式字串中的每個物件都以有索引的格式項目來表示。 格式項目的索引對應至其所表示的物件在方法的參數清單中的位置。 索引以零為起始。 例如,在下列對 String.Format 方法的呼叫中,第一個格式項目 {0:D}
由 thatDate
的字串表示所取代、第二個格式項目 {1}
由 item1
的字串表示所取代,而第三個格式項目 {2:C2}
由 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.
除了取代具有對應物件字串表示格式的項目,格式項目也可讓您控制下列幾項:
當物件實作 IFormattable 介面,並支援格式字串時,物件表示為字串的特定方式。 您可將格式項目索引後面接上
:
(冒號) ,後面再接有效的格式字串,以執行此作業。 上述範例會使用 「d」 (簡短日期模式) 格式字串來格式化日期值,{0:d}
並使用 「C2」 格式字串來格式化數值,例如,{2:C2}
將數位表示為具有兩個小數位數的貨幣值。包含物件字串表示法及在該欄位中對齊方式的字串表示法之欄位寬度。 您可將格式項目索引後面接上
,
(逗號) ,後面再接欄位寬度,以執行此作業。 如果欄位寬度是正值,則此欄位中的字串為靠右對齊;如果欄位寬度是負值,則為靠左對齊。 下列範例在長 20 個字元的欄位中將日期值靠左對齊,並在長 11 個字元的欄位中將具有一位小數位數的十進位值靠右對齊。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
請注意如果對齊字串元件和格式字串元件都存在,則前者優先於後者 (例如,
{0,-20:g}
)。
如需複合格式的詳細資訊,請參閱 Composite Formatting。
使用 ICustomFormatter 的自訂格式
String.Format(IFormatProvider, String, Object[]) 和 StringBuilder.AppendFormat(IFormatProvider, String, Object[])這兩個複合格式方法包含支援自訂格式的格式提供者參數。 呼叫這些其中一個格式化方法時,方法會將表示 Type 介面的 ICustomFormatter 物件傳遞至格式提供者的 GetFormat 方法。 然後, GetFormat 方法負責傳回 ICustomFormatter 實作,這個實作提供自訂格式。
ICustomFormatter 介面具有單一方法 Format(String, Object, IFormatProvider),複合格式化方法會自動針對複合格式字串中的每個格式項目,各呼叫一次這個方法。 Format(String, Object, IFormatProvider) 方法具有三個參數:格式字串 (表示格式項目中的 formatString
引數)、要格式化的物件,以及提供格式化服務的 IFormatProvider 物件。 實作 ICustomFormatter 的物件通常也會實作 IFormatProvider,所以這最後一個參數是對自訂格式化類別的參考。 方法會傳回要格式化之物件的自訂格式化字串表示。 如果方法無法格式化物件,則應該傳回 null 參考 (在 Visual Basic 中為Nothing
)。
下列範例提供一個名為 ICustomFormatter 的 ByteByByteFormatter
實作,這個實作會將整數值顯示為一連串由兩位數十六進位值再加上一個空格所組成的數列。
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
下列範例會使用 ByteByByteFormatter
類別來格式化整數值。 請注意,ICustomFormatter.Format 方法在第二個 String.Format(IFormatProvider, String, Object[]) 方法呼叫中不只呼叫一次,且會在第三個方法呼叫中使用預設的 NumberFormatInfo 提供者,因為。ByteByByteFormatter.Format
方法無法辨識 "N0" 格式字串且傳回 Null 參考 (在 Visual Basic 中為 Nothing
)。
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
另請參閱
標題 | 定義 |
---|---|
標準數值格式字串 \(部分機器翻譯\) | 說明建立數值常用之字串表示的標準格式字串。 |
自訂數值格式字串 | 說明建立應用程式專屬數值格式的自訂格式字串。 |
標準日期和時間格式字串 | 說明建立 DateTime 值之常用字串表示的標準格式字串。 |
自訂日期和時間格式字串 | 說明建立應用程式專屬 DateTime 值格式的自訂格式字串。 |
標準 TimeSpan 格式字串 | 說明建立時間間隔之常用字串表示的標準格式字串。 |
自訂 TimeSpan 格式字串 | 說明建立應用程式專屬數值格式的自訂格式字串。 |
Enumeration Format Strings | 說明用來建立列舉值之字串表示的標準格式字串。 |
複合格式 | 描述如何將一個或更多的格式化值嵌入字串。 字串可以隨後顯示在主控台 (Console) 或寫入資料流。 |
Parsing Strings | 說明如何將物件初始化為這些物件的字串表示所描述的值。 剖析是格式化的反向作業。 |