다음을 통해 공유


형식 문자열 사용자 지정

업데이트: 2007년 11월

.NET Framework는 사용자 정의 형식 문자열을 허용하는 고유의 ToString 메서드를 만들거나 고유의 Format 메서드를 호출하여 형식의 사용자 지정 형식 지정을 수행하는 형식 공급자를 만들 수 있도록 기본 제공된 형식 지정 메커니즘을 확장할 수 있게 지원합니다. IFormattable 인터페이스를 구현하여 고유의 ToString 메서드를 만들고 ICustomFormatterIFormatProvider 인터페이스를 구현하여 고유의 Format 메서드를 만듭니다.

이 단원에서는 사용자 정의 형식 및 기존의 기본 형식에 사용자 지정 형식 문자열을 추가하는 내용만 다루지만 다른 형식에도 이러한 원리를 적용할 수 있습니다.

사용자 지정 형식의 사용자 지정 형식 문자열 추가

사용자 지정 형식을 만드는 경우 IFormattable 인터페이스와 이 인터페이스의 ToString 메서드를 구현하여 고유의 사용자 지정 형식 문자열을 처리하기 위한 지원을 추가할 수 있습니다. 즉, 사용자 지정 형식에서 인식하는 형식 문자열을 제어할 수 있습니다. 사용자 지정 형식에 단순히 ToString 메서드를 추가하는 대신 IFormattable 인터페이스를 구현하면 ToString 메서드 사용자는 미리 정의된 호출 구문 및 반환 형식을 사용할 수 있습니다.

IFormattable 인터페이스의 ToString 메서드는 형식 문자열 매개 변수와 형식 공급자 매개 변수를 사용합니다. 형식 문자열 매개 변수가 비어 있는 문자열이거나 null(Visual Basic에서는 Nothing)이면 기본 형식 지정을 수행합니다. 형식 공급자가 null이면 기본 형식 공급자를 사용합니다.

사용자 지정 형식 문자열이 사용자 지정 버전의 ToString에 전달되는 경우 적절한 형식 지정을 수행합니다. 그렇지 않으면 적절한 .NET Framework 메서드를 호출하여 표준 형식 지정을 수행합니다.

다음 예제에서 MyType 사용자 지정 형식은 IFormattable 인터페이스를 구현합니다. MyType 클래스의 새 인스턴스를 만들고 "b" 사용자 지정 형식 문자열을 인스턴스의 ToString 메서드에 전달하는 경우 Convert.ToString이 오버로드되어 인스턴스 값이 이진(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", 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

기존 형식에 사용자 지정 형식 문자열 추가

기존의 기본 형식의 형식을 지정하는 방법을 제어하고 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(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 메서드는 MyFormat에 정의된 사용자 지정 Format 메서드를 사용하여 MyInt의 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})
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

기타 리소스

형식 지정