Bagikan melalui


Cara: Menentukan dan Menggunakan Penyedia Format Numerik Kustom

.NET memberi Anda kontrol yang luas atas representasi string nilai numerik. Ini mendukung fitur berikut untuk menyesuaikan format nilai numerik:

  • String format numerik standar, yang menyediakan serangkaian format yang telah ditentukan sebelumnya untuk mengonversi angka ke representasi stringnya. Anda dapat menggunakannya dengan metode pemformatan numerik apa pun, seperti Decimal.ToString(String), yang memiliki parameter format. Untuk detailnya, lihat String Format Numerik Standar.

  • String format numerik kustom, yang menyediakan sekumpulan simbol yang dapat digabungkan untuk menentukan penentu format numerik kustom. Anda dapat menggunakannya dengan metode pemformatan numerik apa pun, seperti Decimal.ToString(String), yang memiliki parameter format. Untuk detailnya, lihat String Format Numerik Kustom.

  • Kustom objek CultureInfo atau NumberFormatInfo, yang menentukan simbol dan pola format yang digunakan dalam menampilkan representasi string nilai numerik. Anda dapat menggunakannya dengan metode pemformatan numerik apa pun, seperti ToString, yang memiliki parameter provider. Biasanya, parameter provider digunakan untuk menentukan pemformatan khusus budaya.

Dalam beberapa kasus (seperti saat aplikasi harus menampilkan nomor akun yang diformat, nomor identifikasi, atau kode pos) ketiga teknik ini tidak pantas. .NET juga memungkinkan Anda menentukan objek pemformatan yang bukan objek CultureInfo atau NumberFormatInfo untuk menentukan bagaimana nilai numerik diformat. Topik ini menyediakan instruksi langkah demi langkah untuk menerapkan objek tersebut, dan memberikan contoh yang memformat nomor telepon.

Menentukan penyedia format kustom

  1. Tentukan kelas yang mengimplementasikan antarmuka IFormatProviderdan ICustomFormatter.

  2. Mengimplementasikan metode IFormatProvider.GetFormat. GetFormat adalah metode panggilan balik yang dipanggil metode pemformatan (seperti metode String.Format(IFormatProvider, String, Object[])) untuk mengambil objek yang benar-benar bertanggung jawab untuk melakukan pemformatan kustom. Implementasi umum GetFormat melakukan hal berikut:

    1. Menentukan apakah objek Type yang diteruskan sebagai parameter metode mewakili antarmuka ICustomFormatter.

    2. Jika parameter mewakili antarmuka ICustomFormatter, GetFormat mengembalikan objek yang mengimplementasikan antarmuka ICustomFormatter yang bertanggung jawab untuk menyediakan pemformatan kustom. Biasanya, objek pemformatan kustom mengembalikan dirinya sendiri.

    3. Jika parameter tidak mewakili antarmuka ICustomFormatter, GetFormat mengembalikan null.

  3. Mengimplementasikan metode Format. Metode ini dipanggil dengan metode String.Format(IFormatProvider, String, Object[]) dan bertanggung jawab untuk mengembalikan representasi string dari angka. Menerapkan metode ini biasanya melibatkan hal-hal berikut:

    1. Secara opsional, pastikan bahwa metode ini secara sah dimaksudkan untuk menyediakan layanan pemformatan dengan memeriksa parameter provider. Untuk memformat objek yang mengimplementasikan IFormatProvider dan ICustomFormatter, ini melibatkan pengujian parameter provider untuk kesetaraan dengan objek pemformatan saat ini.

    2. Tentukan apakah objek pemformatan harus mendukung penentu format kustom. (Misalnya, penentu format "N" mungkin menunjukkan bahwa nomor telepon AS harus output dalam format NANP, dan "I" mungkin menunjukkan output dalam format Rekomendasi ITU-T E.123.) Jika penentu format digunakan, metode harus menangani penentu format tertentu. Ini diteruskan ke metode dalam parameter format. Jika tidak ada penentu, nilai parameter format adalah String.Empty.

    3. Mengambil nilai numerik yang diteruskan ke metode sebagai parameter arg. Melakukan manipulasi apa pun yang diperlukan untuk mengonversinya ke representasi stringnya.

    4. Mengembalikan representasi string dari parameter arg.

Menggunakan objek pemformatan numerik kustom

  1. Membuat instans baru dari kelas pemformatan kustom.

  2. Panggil metode pemformatan String.Format(IFormatProvider, String, Object[]), berikan objek pemformatan kustom, penentu pemformatan (atau String.Empty, jika tidak digunakan), dan nilai numerik yang akan diformat.

Contoh

Contoh berikut mendefinisikan penyedia format numerik kustom bernama TelephoneFormatter yang mengonversi angka yang mewakili nomor telepon AS ke format NANP atau E.123-nya. Metode ini menangani dua penentu format, "N" (yang menghasilkan format NANP) dan "I" (yang menghasilkan format E.123 internasional).

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

Penyedia format numerik kustom hanya dapat digunakan dengan metode String.Format(IFormatProvider, String, Object[]). Kelebihan metode pemformatan numerik lainnya (seperti ToString) yang memiliki parameter jenis IFormatProvider semua melewati implementasi IFormatProvider.GetFormat objek Type yang mewakili jenis NumberFormatInfo. Sebagai gantinya, mereka mengharapkan metode untuk mengembalikan objek NumberFormatInfo. Jika tidak, penyedia format numerik kustom diabaikan, dan objek NumberFormatInfo untuk budaya saat ini digunakan di tempatnya. Dalam contoh, metode TelephoneFormatter.GetFormat menangani kemungkinan bahwa metode tersebut mungkin secara tidak pantas diteruskan ke metode pemformatan numerik dengan memeriksa parameter metode dan mengembalikan null jika mewakili jenis selain ICustomFormatter.

Jika penyedia format numerik kustom mendukung sekumpulan penentu format, pastikan Anda memberi perilaku default jika tidak ada penentu format yang disediakan dalam item format yang digunakan dalam panggilan metode String.Format(IFormatProvider, String, Object[]). Dalam contoh, "N" adalah penentu format default. Ini memungkinkan angka dikonversi ke nomor telepon yang diformat dengan menyediakan penentu format eksplisit. Contoh berikut mengilustrasikan panggilan metode seperti itu.

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

Tetapi ini juga memungkinkan konversi terjadi jika tidak ada penentu format. Contoh berikut mengilustrasikan panggilan metode seperti itu.

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

Jika tidak ada penentu format default yang ditentukan, implementasi metode ICustomFormatter.Format Anda harus menyertakan kode seperti berikut ini sehingga .NET dapat menyediakan pemformatan yang tidak didukung kode Anda.

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

Dalam kasus contoh ini, metode yang menerapkan ICustomFormatter.Format dimaksudkan untuk berfungsi sebagai metode panggilan balik untuk metodeString.Format(IFormatProvider, String, Object[]). Oleh karena itu, ia memeriksa parameter formatProvider untuk menentukan apakah berisi referensi ke objek TelephoneFormatter saat ini. Namun, metode ini juga dapat dipanggil langsung dari kode. Dalam hal ini, Anda dapat menggunakan parameter formatProvider untuk menyediakan objek CultureInfo atau NumberFormatInfo yang menyediakan informasi pemformatan khusus budaya.