16.6 Implement a Formattable Type


Problem

You need to implement a type that you can use in formatted strings, which can create different string representations of its content based on the use of format specifiers.

Solution

Implement the System.IFormattable interface.

Discussion

The following code fragment demonstrates the use of format specifiers in the WriteLine method of the System.Console class. The codes in the braces ( emphasized in the example) are the format specifiers.

 double a = 345678.5678; uint b = 12000; byte c = 254; Console.WriteLine("a =  {0}  , b =  {1}  , and c =  {2}  ", a, b, c); Console.WriteLine("a =  {0:c0}  , b =  {1:n4}  , and c =  {2,10:x5}  ", a, b, c); 

When run on a machine configured with English (U.K.) regional settings, this code will result in the output shown here. As you can see, changing the contents of the format specifiers changes the format of the output significantly even though the data has not changed.

 a = 345678.5678, b = 12000, and c = 254 a = 345,679, b = 12,000.0000, and c =      000fe 

To enable support for format specifiers in your own types, you must implement the IFormattable interface. IFormattable declares a single method named ToString with the following signature:

 string ToString(string format, IFormatProvider formatProvider); 

The format argument is a System.String containing a format string . The format string is the portion of the format specifier that follows the colon . For example, in the format specifier {2,10:x5}, from the previous example, "x5" is the format string. The format string contains the instructions the IFormattable instance should use when it's generating the string representation of its content. The .NET Framework documentation for IFormattable states that types that implement IFormattable must support the "G" (general) format string, but that the other supported format strings are implementation dependent. The format argument will be null if the format specifier doesn't include a format string component, for example {0} or {1,20}.

The formatProvider argument is a reference to a System.IFormatProvider instance, which provides access to information about the cultural and regional preferences to use when generating the string representation of the IFormattable object. This information includes data such as the appropriate currency symbol to use or the number of decimal places to use. By default, formatProvider is null , which means you should use the current thread's regional and cultural settings, which are available through the static method CurrentCulture of the System.Globalization.CultureInfo class. Some methods that generate formatted strings, such as String.Format , allow you to specify an alternative IFormatProvider to use.

The .NET Framework uses IFormattable primarily to support the formatting of value types, but it can be used to good effect with any type. The following example contains a class named Person that implements the IFormattable interface. The Person class contains the title and names of a person and will render the person name in different formats depending on the format strings provided. The Person class doesn't make use of regional and cultural settings provided by the formatProvider argument.

 using System; public class Person : IFormattable {     // Private members to hold the person's title and name details.     private string title;     private string[] names;     // Constructor used to set the person's title and names.     public Person(string title, params string[] names) {         this.title = title;         this.names = names;     }     // Override the Object.ToString method to return the person's     // name using the general format.     public override string ToString() {         return ToString("G", null);     }     // Implementation of the IFormattable.ToString method to return the      // person's name in different forms based on the format string     // provided.     public string ToString(string format, IFormatProvider formatProvider) {         string result = null;         // Use the general format if none is specified         if (format == null) format = "G";         // The contents of the format string determine the format of the         // name returned.         switch (format.ToUpper()[0]) {             case 'S':                 // Use short form - first initial and surname                 result = names[0][0] + ". " + names[names.Length-1];                 break;             case 'P':                 // Use polite form - title, initials, and surname                 // Add the person's title to the result                 if (title != null && title.Length != 0) {                     result = title + ". ";                 }                 // Add the person's initials and surname                 for (int count = 0; count < names.Length; count++) {                                        if (count != (names.Length - 1)) {                         result += names[count][0] + ". ";                     } else {                         result += names[count];                     }                 }                 break;             case 'I':                 // Use informal form - first name only                 result = names[0];                 break;             case 'G':             default:                 // Use general/default form - first name and surname                 result = names[0] + " " + names[names.Length-1];                 break;         }         return result;     } } 

The following code demonstrates how to use the formatting capabilities of the Person class:

 // Create a Person object representing a man with the name // Mr. Richard Glen David Peters. Person person =      new Person("Mr", "Richard", "Glen", "David", "Peters"); // Display the person's name using a variety of format strings. System.Console.WriteLine("Dear {0:G},", person); System.Console.WriteLine("Dear {0:P},", person); System.Console.WriteLine("Dear {0:I},", person); System.Console.WriteLine("Dear {0},", person); System.Console.WriteLine("Dear {0:S},", person); 

When executed, the code produces the following output:

 Dear Richard Peters, Dear Mr. R. G. D. Peters, Dear Richard, Dear Richard Peters, Dear R. Peters, 



C# Programmer[ap]s Cookbook
C# Programmer[ap]s Cookbook
ISBN: 735619301
EAN: N/A
Year: 2006
Pages: 266

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net