Skip Navigation LinksHome > View Post

Formatting with ToString and IFormattable

Every class you create will inherit the ToString() method from System.Object which defaults to "[Namespace].[ClassName]". I like to override this method to return something more sensible from my class. For this example I am going to use the very simple Employee class shown below. This class returns "[FirstName] [LastName] ([EmployeeId])" as the default implementation of ToString().


namespace Formattable
{
    public class Employee
    {
        private string _firstName;
        private string _lastName;
        private string _employeeId;

        public string FirstName
        {
            get { return _firstName; }
            set { _firstName = value; }
        }

        public string LastName
        {
            get { return _lastName; }
            set { _lastName = value; }
        }

        public string EmployeeId
        {
            get { return _employeeId; }
            set { _employeeId = value; }
        }

        /// <summary>
        /// Apply default formatting.
        /// Better than "Formattable.Employee"
        /// which is inherited from System.Object
        /// </summary>
        /// <returns>Format example "John Doe (123456)"</returns>
        public override string ToString()
        {
            return string.Format("{0} {1} ({2})", _firstName, _lastName, _employeeId);
        }

    }
}

Now what if you wanted to display the full name only without the EmployeeId? I have often seen code like the one below added to classes. With this addition to the Employee class it would now be possible to bind to the FullName property and get the desired result.


/// <summary>
/// For display purpose only
/// </summary>
public string FullName
{
    get
    {
        return string.Format("{0} {1}", _firstName, _lastName);
    }
}

Allthough this works fine, what would you do if you want to display the full name in the format "[LastName], [FirsName]"? You would have to add another property and call it what? FullName2? Fortunately the .NET framework has a nice and easy solution for this.

Introducing the IFormattable interface

By implementing the IFormattable interface you can provide an easy way of formatting your class without adding extra properties to it. It takes a format parameter of type string and a provider property of type IFormatProvider.

For brevity I am going to ignore the provider parameter but you can read more about the IFormatProvider interface here.

My implementation of the Employee class now looks like this (without the FullName property):


public class Employee : IFormattable
{
    // Properties FirstName, LastName and EmployeeId like above but omitted for brevity

    /// <summary>
    /// Apply default formatting.
    /// Better than "Formattable.Employee"
    /// which is inherited from System.Object
    /// </summary>
    /// <returns>Format example "John Doe (123456)"</returns>
    public override string ToString()
    {
        return string.Format("{0} {1} ({2})", _firstName, _lastName, _employeeId);
    }

    #region IFormattable Members

    public string ToString(string format, IFormatProvider formatProvider)
    {
        switch (format.ToLower())
        {
            // John Doe
            case "f":
                return string.Format("{0} {1}", _firstName, _lastName);
            // Doe, John
            case "lf":
                return string.Format("{0}, {1}", _lastName, _firstName);
            // 123456: John Doe
            case "e":
                return string.Format("{0}: {1} {2}", _employeeId, _firstName, _lastName);
            default:
                return ToString();
        }
    }

    #endregion
}

When using databinding it is now a doddle to apply a custom format to your class to display it in different manners. See the image below as an example of how this can be displayed. Notice that I have marked the textboxes which display the formatted values as ReadOnly to indicate that these are not two way bindable.

Formatted employee

 
Bruusi Post By Bruusi
6:16 AM
12 Apr 2007

» Next Post: Logging Levels and how to use them
« Previous Post: Good news for MSDN subscribers

Comments are closed for this post.

Posted by Alan Le @ 12 Apr 2007 10:16 AM
Thanks for the clear explanation.

© 2005 - 2014 Josh Twist - All Rights Reserved.