asp.net.ph

Skip Navigation LinksHome > Getting Started > ASP.NET Base Types > Format Specifiers and Providers > Customizing Format Strings

Customizing Format Strings

Getting Started   ASP.NET Base Types   Formatting Base Types


If your application requires additional formatting functionality not provided by one of the built-in format strings, you could either create your own base type that accepts a user-defined format string, or create a new format provider class to pass to an existing base type that defines a custom format scheme. All base types implement the IFormattable interface and have the ability to accept custom format schemes through a custom class that implements the IFormatProvider interface.

The base types that implement the IFormattable interface combined with format providers that implement the IFormatProvider interface provide the following functionality:

  • Conversion of numbers, dates, and times to strings using a built-in set of format specifiers.
  • Extensibility through overriding the IFormatProvider object, allowing you to extend the format specifiers offered for base types.
  • Enhancement of custom types by allowing built-in and custom format specifiers to be applied through the ToString method.

Adding Custom Format Strings for Custom Types

When you create your own custom type, you should implement the IFormattable interface, which requires you to implement at least one version of the ToString method. This method allows your type to accept a custom format provider, or define your own format scheme internally, or both. Furthermore, the default ToString method inherited from System.Object can be overridden to return a string that is formatted in your own custom scheme. Additional overloads of ToString can be defined that accept just a format specifier, or just a format provider. When a format specifier is not supplied, your class should provide a default way to format your custom base type, and when no format provider is supplied, your class should provide a default format provider.

Note that by implementing IFormattable, a new type needs to provide a version of the ToString method that consumes a format and a provider. If the format is recognized, the provider is ignored and the exposed value is formatted as a binary value. In all other cases, control is delegated to the Integer.ToString method. This is a standard approach to designing your own types that implement IFormattable. You should provide your own interpretations of specific formats ( consuming the format provider if needed ), and otherwise pass control back to the standard formatting provided through the intrinsic equivalent ToString method of the exposed data type, as needed.

The following code example illustrates the creation of a custom type called myType. This example adds a custom format specifier, b, that returns a binary representation of the type’s value.

 [ VB ]
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
 [ C# ]
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 );
         }
   }
}

The preceding code illustrates the creation of a custom type that accepts and stores an integer value. Whenever a format specifier is passed to the ToString method, a string crated by the Convert.ToString method is returned. If the custom value "b" is passed, an overload of Convert.ToString is called that can format values into one of several numbering systems ( base 2, base 8, base 10, or base 16 ). In this case, a 2 is passed and the binary representation of the value held in this type is returned. If "b" is not passed, then the value falls through to the standard String.Format method, which uses the format provider associated with the current thread to format the value.

You can create a new instance of the myType class and pass it the newly created b format string as shown in the following code example.

 [ VB ]
Dim mtype As New myType ( 42 )
Dim myString As String = mtype.ToString ( "b", null )
Dim YourString As String = mtype.ToString ( "p", null )
’ myString has the value: "101010".
’ YourString has the value: "42 %".
 [ C# ]
myType mtype = new myType ( 42 );
String myString = mtype.ToString ( "b", null );
String YourString = mtype.ToString ( "p", null );
// myString has the value: "101010".
// YourString has the value: "42 %".

Adding Custom Format Strings to Existing Types

By creating a format provider class that implements IFormatProvider and ICustomFormatter, you can provide additional codes for formatting base types in an already defined class. When you pass a format provider to a base type using its ToString method, the base type uses the passed format provider to define its formatting rules, rather than the default format provider. To create a custom format provider you should do the following:

  1. Define a class that implements the two previously mentioned interfaces and overrides GetFormat and Format.
  2. Pass that class into a method ( like String.Format ) that takes the IFormatProvider as a parameter. Doing so causes String.Format to recognize the custom format scheme defined in the new format provider class.

The following code example defines a class that adds a custom Format method that can produce different base values of an integer.

 [ VB ]
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, then 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, then pass the format specifier to the 
         ’ objects ToString method for formatting.
         If TypeOf arg Is IFormattable Then
            return CType ( arg, IFormattable ).ToString ( format, provider )
         End If
         ’ If the object does not support IFormattable, then 
         ’ call the objects ToString method with no additional
         ’ Formattin. 
         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
 [ C# ]
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, then 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, then 
         //call the objects ToString method with no additional
         //Formattin. 
         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 );
   }
}

The following code example uses the custom Format method defined in myFormat to display the base-16 representation of myInt from String.Format.

 [ VB ]
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 } )
’ myString has the value: "42 in custom B16 format is 2a".
 [ C# ]
int myInt = 42;
string myString = String.Format ( new myFormat ( ), "{0} in the custom B16 format is {1:B16}", new object  [ ] { myInt, myInt } );
// myString has the value: "42 in custom B16 format is 2a".


© 2025 Reynald Nuñez and asp.net.ph. All rights reserved.

If you have any question, comment or suggestion
about this site, please send us a note