방법: 사용자 지정 숫자 형식 공급 기업 정의 및 사용How to: Define and Use Custom Numeric Format Providers

.NET Framework에서는 숫자 값의 문자열 표현을 광범위하게 제어할 수 있습니다.The .NET Framework gives you extensive control over the string representation of numeric values. 숫자 값의 형식을 사용자 지정하기 위한 다음과 같은 기능을 지원합니다.It supports the following features for customizing the format of numeric values:

  • 숫자를 해당 문자열 표현으로 변환하기 위한 미리 정의된 형식 집합을 제공하는 표준 숫자 형식 문자열입니다.Standard numeric format strings, which provide a predefined set of formats for converting numbers to their string representation. format 매개 변수가 있는 숫자 서식 지정 메서드(예: Decimal.ToString(String))와 함께 사용할 수 있습니다.You can use them with any numeric formatting method, such as Decimal.ToString(String), that has a format parameter. 자세한 내용은 표준 숫자 형식 문자열을 참조하세요.For details, see Standard Numeric Format Strings.

  • 함께 결합되어 사용자 지정 숫자 형식 지정자를 정의할 수 있는 기호 집합을 제공하는 사용자 지정 숫자 형식 문자열입니다.Custom numeric format strings, which provide a set of symbols that can be combined to define custom numeric format specifiers. 또한 format 매개 변수가 있는 숫자 서식 지정 메서드(예: Decimal.ToString(String))와 함께 사용할 수도 있습니다.They can also be used with any numeric formatting method, such as Decimal.ToString(String), that has a format parameter. 자세한 내용은 사용자 지정 숫자 형식 문자열을 참조하세요.For details, see Custom Numeric Format Strings.

  • 숫자 값의 문자열 표현을 표시하는 데 사용되는 기호 및 형식 패턴을 정의하는 사용자 지정 CultureInfo 또는 NumberFormatInfo 개체입니다.Custom CultureInfo or NumberFormatInfo objects, which define the symbols and format patterns used in displaying the string representations of numeric values. provider 매개 변수가 있는 숫자 서식 지정 메서드(예: ToString)와 함께 사용할 수 있습니다.You can use them with any numeric formatting method, such as ToString, that has a provider parameter. 일반적으로 provider 매개 변수는 문화권별 서식 지정에 사용됩니다.Typically, the provider parameter is used to specify culture-specific formatting.

애플리케이션에서 형식이 지정된 계정 번호, ID 번호 또는 우편 번호를 표시해야 하는 경우와 같이 이 세 가지 방법이 부적절한 경우도 있습니다.In some cases (such as when an application must display a formatted account number, an identification number, or a postal code) these three techniques are inappropriate. .NET Framework에서는 CultureInfo 또는 NumberFormatInfo 개체가 아닌 서식 지정 개체를 정의하여 숫자 값의 서식 지정 방법을 결정할 수도 있습니다.The .NET Framework also enables you to define a formatting object that is neither a CultureInfo nor a NumberFormatInfo object to determine how a numeric value is formatted. 이 항목에서는 이러한 개체를 구현하기 위한 단계별 지침을 제공하고 전화 번호 형식을 지정하는 예제를 제공합니다.This topic provides the step-by-step instructions for implementing such an object, and provides an example that formats telephone numbers.

사용자 지정 형식 공급자를 정의하려면To define a custom format provider

  1. IFormatProviderICustomFormatter 인터페이스를 구현하는 클래스를 정의합니다.Define a class that implements the IFormatProvider and ICustomFormatter interfaces.

  2. IFormatProvider.GetFormat 메서드를 구현합니다.Implement the IFormatProvider.GetFormat method. GetFormat은 서식 지정 메서드(예: String.Format(IFormatProvider, String, Object[]) 메서드)가 실제로 사용자 지정 서식 지정을 수행하는 개체를 검색하기 위해 호출하는 콜백 메서드입니다.GetFormat is a callback method that the formatting method (such as the String.Format(IFormatProvider, String, Object[]) method) invokes to retrieve the object that is actually responsible for performing custom formatting. 일반적인 GetFormat 구현에서는 다음 작업을 수행합니다.A typical implementation of GetFormat does the following:

    1. 메서드 매개 변수로 전달되는 Type 개체가 ICustomFormatter 인터페이스를 나타내는지 여부를 결정합니다.Determines whether the Type object passed as a method parameter represents an ICustomFormatter interface.

    2. 매개 변수가 ICustomFormatter 인터페이스를 나타내지 않는 경우 GetFormat은 사용자 지정 서식 지정을 제공하는 ICustomFormatter 인터페이스를 구현하는 개체를 반환합니다.If the parameter does represent the ICustomFormatter interface, GetFormat returns an object that implements the ICustomFormatter interface that is responsible for providing custom formatting. 일반적으로 사용자 지정 형식 지정 개체 자체가 반환됩니다.Typically, the custom formatting object returns itself.

    3. 매개 변수가 ICustomFormatter 인터페이스를 나타내지 않는 경우 GetFormatnull을 반환합니다.If the parameter does not represent the ICustomFormatter interface, GetFormat returns null.

  3. Format 메서드를 구현합니다.Implement the Format method. 이 메서드는 String.Format(IFormatProvider, String, Object[]) 메서드에 의해 호출되며 숫자의 문자열 표현을 반환합니다.This method is called by the String.Format(IFormatProvider, String, Object[]) method and is responsible for returning the string representation of a number. 일반적으로 메서드를 구현하는 과정은 다음과 같습니다.Implementing the method typically involves the following:

    1. 필요에 따라 provider 매개 변수를 검사하여 메서드가 서식 지정 서비스를 제공하기에 적합한지 확인합니다.Optionally, make sure that the method is legitimately intended to provide formatting services by examining the provider parameter. IFormatProviderICustomFormatter를 둘 다 구현하는 서식 지정 개체의 경우 provider 매개 변수가 현재 서식 지정 개체와 같은지 테스트해야 합니다.For formatting objects that implement both IFormatProvider and ICustomFormatter, this involves testing the provider parameter for equality with the current formatting object.

    2. 형식 지정 개체가 사용자 지정 형식 지정자를 지원해야 하는지 여부를 결정합니다.Determine whether the formatting object should support custom format specifiers. 예를 들어 "N" 형식 지정자는 미국 전화 번호가 NANP 형식으로, "I" 형식 지정자는 ITU-T 권장 E.123 형식으로 출력되어야 함을 나타낼 수 있습니다. 형식 지정자가 사용된 경우 메서드에서 특정 형식 지정자를 처리해야 합니다.(For example, an "N" format specifier might indicate that a U.S. telephone number should be output in NANP format, and an "I" might indicate output in ITU-T Recommendation E.123 format.) If format specifiers are used, the method should handle the specific format specifier. 지정자는 format 매개 변수의 메서드에 전달됩니다.It is passed to the method in the format parameter. 지정자가 없는 경우 format 매개 변수의 값은 String.Empty입니다.If no specifier is present, the value of the format parameter is String.Empty.

    3. 메서드에 arg 매개 변수로 전달된 숫자 값을 검색합니다.Retrieve the numeric value passed to the method as the arg parameter. 문자열 표현으로 변환하는 데 필요한 조작을 수행합니다.Perform whatever manipulations are required to convert it to its string representation.

    4. arg 매개 변수의 문자열 표현을 반환합니다.Return the string representation of the arg parameter.

사용자 지정 숫자 형식 지정 개체를 사용하려면To use a custom numeric formatting object

  1. 사용자 지정 형식 지정 클래스의 새 인스턴스를 만듭니다.Create a new instance of the custom formatting class.

  2. String.Format(IFormatProvider, String, Object[]) 서식 지정 메서드를 호출하여 사용자 지정 서식 지정 개체, 형식 지정자(또는 지정자를 사용하지 않는 경우 String.Empty) 및 서식을 지정할 숫자 값을 전달합니다.Call the String.Format(IFormatProvider, String, Object[]) formatting method, passing it the custom formatting object, the formatting specifier (or String.Empty, if one is not used), and the numeric value to be formatted.

Example

다음 예제에서는 미국 전화 번호를 나타내는 숫자를 NANP 또는 E.123 형식으로 변환하는 TelephoneFormatter라는 사용자 지정 숫자 형식 공급자를 정의합니다.The following example defines a custom numeric format provider named TelephoneFormatter that converts a number that represents a U.S. telephone number to its NANP or E.123 format. 메서드는 두 가지 형식 지정자 "N"(NANP 형식 출력)과 "I"(국제 E.123 형식 출력)를 처리합니다.The method handles two format specifiers, "N" (which outputs the NANP format) and "I" (which outputs the international E.123 format).

using System;
using System.Globalization;

public class TelephoneFormatter : 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)
   {
      // Check whether this is an appropriate callback             
      if (! this.Equals(formatProvider))
         return null; 

      // Set default format specifier             
      if (string.IsNullOrEmpty(format)) 
         format = "N";

      string numericString = arg.ToString();
      
      if (format == "N")
      {
         if (numericString.Length <= 4)
            return numericString;
         else if (numericString.Length == 7)
            return numericString.Substring(0, 3) + "-" + numericString.Substring(3, 4); 
         else if (numericString.Length == 10)
               return "(" + numericString.Substring(0, 3) + ") " +
                      numericString.Substring(3, 3) + "-" + numericString.Substring(6);   
         else
            throw new FormatException( 
                      string.Format("'{0}' cannot be used to format {1}.", 
                                    format, arg.ToString()));
      }
      else if (format == "I")
      {
         if (numericString.Length < 10)
            throw new FormatException(string.Format("{0} does not have 10 digits.", arg.ToString()));
         else
            numericString = "+1 " + numericString.Substring(0, 3) + " " + numericString.Substring(3, 3) + " " + numericString.Substring(6);
      }
      else
      {
         throw new FormatException(string.Format("The {0} format specifier is invalid.", format));
      } 
      return numericString;  
   }
}

public class TestTelephoneFormatter
{
   public static void Main()
   {
      Console.WriteLine(String.Format(new TelephoneFormatter(), "{0}", 0));
      Console.WriteLine(String.Format(new TelephoneFormatter(), "{0}", 911));
      Console.WriteLine(String.Format(new TelephoneFormatter(), "{0}", 8490216));
      Console.WriteLine(String.Format(new TelephoneFormatter(), "{0}", 4257884748));
      
      Console.WriteLine(String.Format(new TelephoneFormatter(), "{0:N}", 0));
      Console.WriteLine(String.Format(new TelephoneFormatter(), "{0:N}", 911));
      Console.WriteLine(String.Format(new TelephoneFormatter(), "{0:N}", 8490216));
      Console.WriteLine(String.Format(new TelephoneFormatter(), "{0:N}", 4257884748));

      Console.WriteLine(String.Format(new TelephoneFormatter(), "{0:I}", 4257884748));
   }
}
Public Class TelephoneFormatter : 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
      ' Check whether this is an appropriate callback             
      If Not Me.Equals(formatProvider) Then Return Nothing 

      ' Set default format specifier             
      If String.IsNullOrEmpty(fmt) Then fmt = "N"

      Dim numericString As String = arg.ToString
      
      If fmt = "N" Then
         Select Case numericString.Length
            Case <= 4 
               Return numericString
            Case 7
               Return Left(numericString, 3) & "-" & Mid(numericString, 4) 
            Case 10
               Return "(" & Left(numericString, 3) & ") " & _
                      Mid(numericString, 4, 3) & "-" & Mid(numericString, 7)   
            Case Else
               Throw New FormatException( _
                         String.Format("'{0}' cannot be used to format {1}.", _
                                       fmt, arg.ToString()))
         End Select
      ElseIf fmt = "I" Then
         If numericString.Length < 10 Then
            Throw New FormatException(String.Format("{0} does not have 10 digits.", arg.ToString()))
         Else
            numericString = "+1 " & Left(numericString, 3) & " " & Mid(numericString, 4, 3) & " " & Mid(numericString, 7)
         End If      
      Else
         Throw New FormatException(String.Format("The {0} format specifier is invalid.", fmt))
      End If 
      Return numericString  
   End Function
End Class

Public Module TestTelephoneFormatter
   Public Sub Main
      Console.WriteLine(String.Format(New TelephoneFormatter, "{0}", 0))
      Console.WriteLine(String.Format(New TelephoneFormatter, "{0}", 911))
      Console.WriteLine(String.Format(New TelephoneFormatter, "{0}", 8490216))
      Console.WriteLine(String.Format(New TelephoneFormatter, "{0}", 4257884748))
      
      Console.WriteLine(String.Format(New TelephoneFormatter, "{0:N}", 0))
      Console.WriteLine(String.Format(New TelephoneFormatter, "{0:N}", 911))
      Console.WriteLine(String.Format(New TelephoneFormatter, "{0:N}", 8490216))
      Console.WriteLine(String.Format(New TelephoneFormatter, "{0:N}", 4257884748))

      Console.WriteLine(String.Format(New TelephoneFormatter, "{0:I}", 4257884748))
   End Sub
End Module

사용자 지정 숫자 형식 공급자는 String.Format(IFormatProvider, String, Object[]) 메서드에서만 사용할 수 있습니다.The custom numeric format provider can be used only with the String.Format(IFormatProvider, String, Object[]) method. IFormatProvider 형식의 매개 변수가 있는 숫자 서식 지정 메서드의 다른 오버로드(예: ToString)는 모두 NumberFormatInfo 형식을 나타내는 Type 개체를 IFormatProvider.GetFormat 구현에 전달합니다.The other overloads of numeric formatting methods (such as ToString) that have a parameter of type IFormatProvider all pass the IFormatProvider.GetFormat implementation a Type object that represents the NumberFormatInfo type. 반환 시 메서드가 NumberFormatInfo 개체를 반환할 것으로 예상합니다.In return, they expect the method to return a NumberFormatInfo object. 반환하지 않을 경우 사용자 지정 숫자 형식 공급자는 무시되고 현재 문화권에 대한 NumberFormatInfo 개체가 대신 사용됩니다.If it does not, the custom numeric format provider is ignored, and the NumberFormatInfo object for the current culture is used in its place. 예제에서 TelephoneFormatter.GetFormat 메서드는 메서드 매개 변수를 검사하고 ICustomFormatter 이외의 다른 형식을 나타내는 경우 null을 반환하여 숫자 서식 지정 메서드에 부적절하게 전달될 수 있는 가능성을 처리합니다.In the example, the TelephoneFormatter.GetFormat method handles the possibility that it may be inappropriately passed to a numeric formatting method by examining the method parameter and returning null if it represents a type other than ICustomFormatter.

사용자 지정 숫자 형식 공급자가 형식 지정자 집합을 지원하는 경우 String.Format(IFormatProvider, String, Object[]) 메서드 호출에 사용된 형식 항목에 형식 지정자가 제공되지 않은 경우의 기본 동작을 제공해야 합니다.If a custom numeric format provider supports a set of format specifiers, make sure you provide a default behavior if no format specifier is supplied in the format item used in the String.Format(IFormatProvider, String, Object[]) method call. 예제에서는 "N"이 기본 형식 지정자입니다.In the example, "N" is the default format specifier. 이렇게 하면 명시적 형식 지정자를 제공하여 숫자를 형식이 지정된 전화 번호로 변환할 수 있습니다.This allows for a number to be converted to a formatted telephone number by providing an explicit format specifier. 다음 예제에서는 이러한 메서드 호출을 보여 줍니다.The following example illustrates such a method call.

Console.WriteLine(String.Format(new TelephoneFormatter(), "{0:N}", 4257884748));
Console.WriteLine(String.Format(New TelephoneFormatter, "{0:N}", 4257884748))

그러나 형식 지정자가 없는 경우에도 변환을 수행할 수 있습니다.But it also allows the conversion to occur if no format specifier is present. 다음 예제에서는 이러한 메서드 호출을 보여 줍니다.The following example illustrates such a method call.

Console.WriteLine(String.Format(new TelephoneFormatter(), "{0}", 4257884748));
Console.WriteLine(String.Format(New TelephoneFormatter, "{0}", 4257884748))

기본 형식 지정자가 정의되어 있지 않으면 .NET이 코드에서 지원하지 않는 서식 지정을 제공할 수 있도록 ICustomFormatter.Format 메서드 구현에 다음과 같은 코드를 포함해야 합니다.If no default format specifier is defined, your implementation of the ICustomFormatter.Format method should include code such as the following so that .NET can provide formatting that your code does not support.

if (arg is IFormattable) 
   s = ((IFormattable)arg).ToString(format, formatProvider);
else if (arg != null)    
   s = arg.ToString();
If TypeOf(arg) Is IFormattable Then 
   s = DirectCast(arg, IFormattable).ToString(fmt, formatProvider)
ElseIf arg IsNot Nothing Then    
   s = arg.ToString()
End If

이 예제의 경우 ICustomFormatter.Format을 구현하는 메서드는 String.Format(IFormatProvider, String, Object[]) 메서드에 대한 콜백 메서드 역할을 하기 위한 것입니다.In the case of this example, the method that implements ICustomFormatter.Format is intended to serve as a callback method for the String.Format(IFormatProvider, String, Object[]) method. 따라서 이 메서드는 formatProvider 매개 변수를 검사하여 현재 TelephoneFormatter 개체에 대한 참조가 있는지 여부를 확인합니다.Therefore, it examines the formatProvider parameter to determine whether it contains a reference to the current TelephoneFormatter object. 그러나 코드에서 메서드를 직접 호출할 수도 있습니다.However, the method can also be called directly from code. 이 경우 formatProvider 매개 변수를 사용하여 문화권별 서식 지정 정보를 제공하는 CultureInfo 또는 NumberFormatInfo 개체를 제공할 수 있습니다.In that case, you can use the formatProvider parameter to provide a CultureInfo or NumberFormatInfo object that supplies culture-specific formatting information.

참고 항목See also