Настройка форматов строк

Обновлен: Ноябрь 2007

.NET Framework поддерживает расширение встроенного механизма форматирования, поэтому можно создать собственный метод ToString, принимающий пользовательские форматы строк, или создать поставщика формата, который вызывает собственный метод Format для выполнения пользовательского форматирования типа. Создать собственный метод ToString можно путем реализации интерфейса IFormattable, а собственный метод Format, реализовав интерфейсы ICustomFormatter и IFormatProvider.

Информация в этой секции ограничена сведениями по добавлению настраиваемых форматов строк к определяемым пользователями типам и существующим базовым типам, но описанные принципы могут также применяться к любому типу.

Добавление строк настраиваемых форматов для пользовательских типов

При создании собственного пользовательского типа можно добавить поддержку обработки собственных строк пользовательского формата, реализовав интерфейс IFormattable и метод ToString этого интерфейса. Это означает, что можно управлять тем, какие строки формата будут распознаваться пользовательским типом. Преимуществом реализации интерфейса IFormattable вместо определения метода ToString для пользовательского типа является то, что пользователи вашего метода ToString используют предопределенный синтаксис вызова и возвращаемого типа.

Входными параметрами метода ToString интерфейса IFormattable являются строка формата и поставщик формата. Если строка формата пуста или равна null (Nothing в Visual Basic), выполняется форматирование по умолчанию. Если поставщик формата равен null, необходимо использовать поставщик формата по умолчанию.

Если в метод ToString передается строка настраиваемого формата, следует выполнять соответствующее форматирование, в противном случае следует вызвать подходящий для форматирования метод .NET Framework.

В следующем примере для типа MyType реализован интерфейс IFormattable. При передаче строки формата "b" в метод ToString для создания нового экземпляра класса MyType перегруженный метод Convert.ToString возвращает строку с двоичным представлением значения экземпляра. Если строка "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);
            }
    }
}

В следующем примере демонстрируется передача строки "b" в метод класса MyType.

Dim mtype As New MyType(42)
Dim myString As String = mtype.ToString("b", Nothing)
Dim yourString As String = mtype.ToString("d", Nothing)
Console.WriteLine(myString)
Console.WriteLine(yourString)
' The example produces the following output:
'       101010
'       42
MyType mtype = new MyType(42);
String myString = mtype.ToString("b", null);
String yourString = mtype.ToString("d", null);
Console.WriteLine(myString);
Console.WriteLine(yourString);
// The example produces the following output:
//       101010
//       42

Добавление строк настраиваемых форматов для существующих типов

Управлять форматированием существующих типов можно с помощью дополнительного кода форматирования, создавая класс поставщика формата, реализующий интерфейсы ICustomFormatter и IFormatProvider.

Если при вызове метода ToString базового типа указан поставщик формата, именно он используется при форматировании типа. Чтобы создать настраиваемый поставщик формата, следует выполнить следующие действия:

  1. Определите класс, реализующий два вышеупомянутых интерфейса и переопределяющий GetFormat и Format.

  2. Передайте этот класс в метод (например, в метод String.Format), который принимает IFormatProvider в качестве параметра. Таким образом, форматирование будет произведено методом 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(theformat, provider)
            ' 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);
    }
}

В следующем примере метод Format использует пользовательский метод Format, определенный в классе MyFormat, для отображения шестнадцатеричного представления MyInt.

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})
Console.WriteLine(myString)
' The example displays the following output:
'      42 in the 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});
Console.WriteLine(myString);                               
// The example displays the following output: 
//       42 in custom B16 format is 2a

См. также

Ссылки

IFormattable

IFormatProvider

ICustomFormatter

Другие ресурсы

Типы форматирования