自訂格式字串

.NET Framework 支援對其內建格式化機制的擴充,所以您可以建立自己的 ToString 方法 (可接受使用者定義的格式字串),或建立格式提供者 (可叫用您自己的 Format 方法) 來執行型別的自訂格式化。您可以藉由實作 IFormattable 介面來建立自己的 ToString 方法,並藉由實作 ICustomFormatterIFormatProvider 介面來建立自己的 Format 方法。

本章節的資訊僅限於將自訂格式字串加入至使用者定義的型別和現有基底型別,但所描述的原則仍然可以適用任何型別。

加入自訂型別的自訂格式字串

如果您建立自己的自訂型別,即可藉由實作 IFormattable 介面和該介面的 ToString 方法來為您自己的自訂格式字串處理提供支援。這表示您可以控制自訂型別所能辨識的格式字串。實作 IFormattable 介面 (而不僅只是將 ToString 方法加入到自訂型別) 的好處,是您可以向您的 ToString 方法使用者保證可以使用預先定義的呼叫語法和傳回型別。

IFormattable 介面的 ToString 方法接受格式字串參數和格式提供者參數。如果格式字串參數為空字串或 null (在 Visual Basic 中為 Nothing),則會執行預設的格式化。如果格式提供者為 null,則使用預設的格式提供者。

如果自訂格式字串要傳遞至您的 ToString 自訂版本,請執行適當的格式化,否則請呼叫適合的 .NET Framework 方法來執行標準格式化。

在下列範例中,MyType 自訂型別會實作 IFormattable 介面。如果您建立 MyType 類別的新執行個體,並將 "b" 自訂格式字串傳遞至執行個體的 ToString 方法,Convert.ToString 的多載會傳回執行個體值的二進位 (Base 2) 字串表示。如果沒有傳遞 "b",執行個體的值會由其本身的 ToString 方法來格式化;也就是,整數 myValue 會由 System.Int32.ToString 方法來格式化。

Public Class MyType
    Implements IFormattable
    ' Assign a value for the class.
    Private myValue As Integer    
    
    ' Add a constructor.
    Public Sub New(value As Integer)
        myValue = value
    End Sub
    
    ' Write a custom Format method for the type.
    Public Overloads Function ToString(format As String, fp As IFormatProvider) As String _
    Implements IFormattable.ToString
    
        If format.Equals("b") Then
            Return Convert.ToString(myValue, 2)
        Else
            Return myValue.ToString(format, fp)
        End If
    End Function
End Class
public class MyType : IFormattable
{
    // Assign a value for the class.
    private int myValue;
    
    // Add a constructor.
    public MyType( int value )
    {
        myValue = value;
    }
    // Write a custom Format method for the type.
    public string ToString(string format, IFormatProvider fp)
    {
        if (format.Equals ("b"))
            {
            return Convert.ToString (myValue, 2);
            }
        else
            {
            return myValue.ToString(format, fp);
            }
    }
}

下列範例示範如何使用 MyType 類別和 "b" 格式字串。

Dim mtype As New MyType(42)
Dim MyString As String = mtype.ToString("b", null)
Dim YourString As String = mtype.ToString("p", null)
' MyString has the value: "101010".
' YourString has the value: "42 %".
MyType mtype = new MyType(42);
String MyString = mtype.ToString("b", null);
String YourString = mtype.ToString("p", null);
// MyString has the value: "101010".
// YourString has the value: "42 %".

加入自訂格式字串至現有型別

您可以藉由建立會實作 ICustomFormatterIFormatProvider 的格式提供者類別來控制現有基底型別格式化的方式,並提供用以格式化的其他程式碼。

當您傳遞格式提供者給基底型別的 ToString 方法時,基底型別會使用傳遞的格式提供者,而非預設的格式提供者,來定義其格式化規則。若要建立自訂格式提供者,您應該執行下列作業:

  1. 定義實作兩個先前提及的介面的類別,並覆寫 GetFormatFormat

  2. 將類別傳入接受 IFormatProvider 做為參數的方法 (像 String.Format)。如此將致使 String.Format 辨識定義於新格式提供者類別中的自訂格式配置。

下列範例定義類別,它會加入可以產生整數各種基底數值的自訂 Format 方法。

Public Class MyFormat
    Implements IFormatProvider
    Implements ICustomFormatter
    
    ' String.Format calls this method to get an instance of an
    ' ICustomFormatter to handle the formatting.
    Public Function GetFormat(service As Type) As Object _
    Implements IFormatProvider.GetFormat
    
        If service.ToString() = GetType(ICustomFormatter).ToString() Then
            Return Me
        Else
            Return Nothing
        End If
    End Function
    
    ' After String.Format gets the ICustomFormatter, it calls this format
    ' method on each argument.
    Public Function Format(theformat As String, arg As Object, provider As IFormatProvider) As String _
    Implements ICustomFormatter.Format
    
        If theformat Is Nothing Then
            Return String.Format("{0}", arg)
        End If
        Dim i As Integer = theformat.Length
            ' If the object to be formatted supports the IFormattable
            ' interface, pass the format specifier to the 
            ' objects ToString method for formatting.
        If Not theformat.StartsWith("B") Then
            ' If the object to be formatted supports the IFormattable
            ' interface, pass the format specifier to the 
            ' objects ToString method for formatting.
            If TypeOf arg Is IFormattable Then
                return CType(arg, IFormattable).ToString(format, provider)
            End If
            ' If the object does not support IFormattable, 
            ' call the objects ToString method with no additional
            ' formatting. 
            ElseIf (arg Is Nothing) Then
                return arg.ToString()
            End If
        End If
        ' Uses the format string to
        ' form the output string.
        theformat = theformat.Trim(New Char() {"B"c})
        Dim b As Integer = Convert.ToInt32(theformat)
        Return Convert.ToString(CInt(arg), b)
    End Function
End Class
public class MyFormat : IFormatProvider, ICustomFormatter
{
    // String.Format calls this method to get an instance of an
    // ICustomFormatter to handle the formatting.
    public object GetFormat (Type service)
    {
        if (service == typeof (ICustomFormatter))
        {
            return this;
        }
        else
        {
            return null;
        }
    }
    // After String.Format gets the ICustomFormatter, it calls this format
    // method on each argument.
    public string Format (string format, object arg, IFormatProvider provider) 
    {
        if (format == null)
        {
            return String.Format ("{0}", arg);
        }
        // If the format is not a defined custom code,
        // use the formatting support in ToString.
        if (!format.StartsWith("B")) 
        {
            //If the object to be formatted supports the IFormattable
            //interface, pass the format specifier to the 
            //objects ToString method for formatting.
            if (arg is IFormattable) 
            {
                return ((IFormattable)arg).ToString(format, provider);
            } 
            //If the object does not support IFormattable, 
            //call the objects ToString method with no additional
            //formatting. 
            else if (arg != null) 
            {
                return arg.ToString();
            }
        }
        // Uses the format string to
        // form the output string.
        format = format.Trim (new char [] {'B'});
        int b = Convert.ToInt32 (format);
        return Convert.ToString ((int)arg, b);
    }
}

在下列範例中,String.Format 方法會使用 MyFormat 中定義的自訂 Format 方法來顯示 MyInt 的 Base 16 表示。

Dim MyInt As Integer = 42
Dim MyString As String = String.Format (New MyFormat (), "{0} in the custom B16 format is {1:B16}", New Object () { MyInt, MyInt } )
' MyString has the value: "42 in custom B16 format is 2a".
int MyInt = 42;
string MyString = String.Format (new MyFormat (), "{0} in the custom B16 format is {1:B16}", new object [] { MyInt, MyInt } );
// MyString has the value: "42 in custom B16 format is 2a".

請參閱

參考

IFormattable Interface
IFormatProvider
ICustomFormatter

其他資源

格式化型別