.NET Framework에서는 숫자 값의 문자열 표현을 다양한 방식으로 제어할 수 있습니다. 숫자 값 형식을 사용자 지정하는 데 사용할 수 있는 기능은 다음과 같습니다.
숫자를 문자열 표현으로 변환하는 데 사용되는 미리 정의된 형식 집합을 제공하는 표준 숫자 형식 문자열. format 매개 변수가 있는 Decimal.ToString(String) 등의 숫자 서식 지정 메서드에 이러한 문자열을 사용할 수 있습니다. 자세한 내용은 표준 숫자 서식 문자열을 참조하십시오.
사용자 지정 숫자 서식 지정자를 정의하기 위해 조합할 수 있는 기호 집합을 제공하는 사용자 지정 숫자 형식 문자열. 이러한 문자열은 format 매개 변수가 있는 Decimal.ToString(String) 등의 숫자 서식 지정 메서드에도 사용할 수 있습니다. 자세한 내용은 사용자 지정 숫자 서식 문자열을 참조하십시오.
숫자 값의 문자열 표현을 표시하는 데 사용되는 기호 및 형식 패턴을 정의하는 사용자 지정 CultureInfo 또는 NumberFormatInfo 개체. provider 매개 변수가 있는 ToString 등의 숫자 서식 지정 메서드에 이러한 개체를 사용할 수 있습니다. 대개 provider 매개 변수는 문화권별 형식을 지정하는 데 사용됩니다.
응용 프로그램에서 서식이 지정된 계좌 번호, ID 번호 또는 우편 번호를 표시해야 하는 등의 일부 경우에는 이 세 가지 기술이 적합하지 않습니다. 또한 .NET Framework에서는 CultureInfo 개체도, NumberFormatInfo 개체도 아닌 서식 지정 개체를 정의하여 숫자 값의 서식 지정 방식을 결정할 수 있습니다. 이 항목에서는 이러한 개체를 구현하기 위한 단계별 지침과 전화 번호 형식을 지정하는 예제를 제공합니다.
사용자 지정 형식 공급자를 정의하려면
IFormatProvider 및 ICustomFormatter 인터페이스를 구현하는 클래스를 정의합니다.
IFormatProvider.GetFormat 메서드를 구현합니다. GetFormat은 String.Format(IFormatProvider, String, Object[]) 메서드와 같은 서식 지정 메서드가 실제로 사용자 지정 서식 지정을 수행하는 개체를 검색하기 위해 호출하는 콜백 메서드입니다. 일반적으로 GetFormat을 구현하면 다음 작업이 수행됩니다.
메서드 매개 변수로 전달되는 Type 개체가 ICustomFormatter 인터페이스를 나타내는지 여부를 확인합니다.
매개 변수가 ICustomFormatter 인터페이스를 나타내는 경우 GetFormat은 사용자 지정 서식 지정을 수행하는 ICustomFormatter 인터페이스를 구현하는 개체를 반환합니다. 일반적으로 사용자 지정 서식 지정 개체는 자기 자신을 반환합니다.
매개 변수가 ICustomFormatter 인터페이스를 나타내지 않으면 GetFormat은 null을 반환합니다.
Format 메서드를 구현합니다. 이 메서드는 String.Format(IFormatProvider, String, Object[]) 메서드에서 호출되며 숫자의 문자열 표현을 반환합니다. 이 메서드를 구현할 때는 대개 다음 작업이 수행됩니다.
선택적으로 provider 매개 변수를 확인하여 이 메서드가 서식 지정 서비스를 제공하기 위한 것인지를 확인합니다. IFormatProvider 및 ICustomFormatter를 모두 구현하는 서식 지정 개체의 경우 여기에는 현재 서식 지정 개체와 같은지 확인하기 위해 provider 매개 변수를 테스트하는 작업이 포함됩니다.
서식 지정 개체가 사용자 지정 서식 지정자를 지원하는지 여부를 확인합니다. 예를 들어 "N" 서식 지정자는 미국 전화 번호가 NANP 형식으로, "I" 서식 지정자는 ITU-T 권장 E.123 형식으로 출력되어야 함을 나타낼 수 있습니다. 서식 지정자를 사용하는 경우 이 메서드가 특정 서식 지정자를 처리해야 합니다. 서식 지정자는 format 매개 변수에서 메서드로 전달됩니다. 지정자가 없으면 format 매개 변수의 값은 String.Empty가 됩니다.
arg 매개 변수로 메서드에 전달된 숫자 값을 검색합니다. 적절히 조작하여 숫자 값을 문자열 표현으로 변환합니다.
arg 매개 변수의 문자열 표현을 반환합니다.
사용자 지정 숫자 서식 지정 개체를 사용하려면
사용자 지정 서식 지정 클래스의 새 인스턴스를 만듭니다.
String.Format(IFormatProvider, String, Object[]) 서식 지정 메서드를 호출하여 사용자 지정 서식 지정 개체, 서식 지정자(지정자를 사용하지 않는 경우 String.Empty) 및 형식을 지정할 숫자 값을 전달합니다.
예제
다음 예제에서는 미국 전화 번호를 나타내는 숫자를 NANP 또는 E.123 형식으로 변환하는 TelephoneFormatter라는 사용자 지정 숫자 형식 공급자를 정의합니다. 이 메서드는 두 서식 지정자, 즉 NANP 형식을 출력하는 "N"과 국제 E.123 형식을 출력하는 "I"를 처리합니다.
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
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));
}
}
사용자 지정 숫자 형식 공급자는 String.Format(IFormatProvider, String, Object[]) 메서드에서만 사용할 수 있습니다. 형식이 IFormatProvider인 매개 변수가 있는 ToString 등의 다른 숫자 서식 지정 메서드 오버로드는 모두 IFormatProvider.GetFormat 구현에 NumberFormatInfo 형식을 나타내는 Type 개체를 전달합니다. 이러한 오버로드를 사용하는 경우 메서드는 NumberFormatInfo 개체를 반환해야 합니다. 그렇지 않으면 사용자 지정 숫자 형식 공급자는 무시되고 현재 문화권의 NumberFormatInfo 개체가 대신 사용됩니다. 예제에서 TelephoneFormatter.GetFormat 메서드는 메서드 매개 변수를 확인하고 매개 변수가 ICustomFormatter 이외의 형식을 나타내는 경우 null을 반환하여 매개 변수가 숫자 서식 지정 메서드로 잘못 전달되지 않도록 처리합니다.
사용자 지정 숫자 형식 공급자가 서식 지정자 집합을 지원하는 경우, String.Format(IFormatProvider, String, Object[]) 메서드 호출에 사용된 형식 항목에 서식 지정자가 제공되지 않으면 기본 동작을 제공해야 합니다. 이 예제에서는 "N"이 기본 서식 지정자입니다. 이렇게 하면 명시적인 서식 지정자를 제공하여 숫자를 서식이 지정된 전화 번호로 변환할 수 있습니다. 다음 예제에서는 이와 같은 메서드 호출을 보여 줍니다.
Console.WriteLine(String.Format(New TelephoneFormatter, "{0:N}", 4257884748))
Console.WriteLine(String.Format(new TelephoneFormatter(), "{0:N}", 4257884748));
그러나 서식 지정자가 없는 경우에도 변환을 수행할 수 있습니다. 다음 예제에서는 이와 같은 메서드 호출을 보여 줍니다.
Console.WriteLine(String.Format(New TelephoneFormatter, "{0}", 4257884748))
Console.WriteLine(String.Format(new TelephoneFormatter(), "{0}", 4257884748));
기본 서식 지정자가 정의되어 있지 않으면 .NET Framework에서 코드가 지원하지 않는 서식 지정을 제공하도록 ICustomFormatter.Format 메서드 구현에 다음과 같은 코드를 포함해야 합니다.
If TypeOf(arg) Is IFormattable Then
s = DirectCast(arg, IFormattable).ToString(fmt, formatProvider)
ElseIf arg IsNot Nothing Then
s = arg.ToString()
End If
if (arg is IFormattable)
s = ((IFormattable)arg).ToString(format, formatProvider);
else if (arg != null)
s = arg.ToString();
이 예제의 경우 ICustomFormatter.Format을 구현하는 메서드는 String.Format(IFormatProvider, String, Object[]) 메서드의 콜백 메서드 역할을 합니다. 그러므로 이 메서드는 현재 TelephoneFormatter 개체에 대한 참조가 포함되어 있는지 formatProvider 매개 변수를 확인합니다. 그러나 이 메서드를 코드에서 직접 호출할 수도 있습니다. 이 경우에는 formatProvider 매개 변수를 사용하여 문화권별 서식 지정 정보를 제공하는 CultureInfo 또는 NumberFormatInfo 개체를 제공할 수 있습니다.
코드 컴파일
csc.exe 또는 vb.exe를 사용하여 명령줄에서 코드를 컴파일합니다. Visual Studio에서 코드를 컴파일하려면 콘솔 응용 프로젝트 템플릿에 코드를 삽입합니다.