Click here to Skip to main content
15,879,326 members
Articles / Programming Languages / C#

Generics Converter for Basic Types

Rate me:
Please Sign up or sign in to vote.
2.36/5 (8 votes)
17 Jun 2010CPOL2 min read 23K   102   6   6
A generics method to convert an object to a basic type.

Screenshot.jpg

Introduction

This article presents a possibility to create a generics conversion method which can be used by the basic types (bool, int, byte, etc.).

Background

There are cases where you want to create generic processing for several different data types which are very similar but don't have a common parent class or don't inherit a common interface. This is very often the case with the basic .NET classes that represent the value types bool, int, byte, etc. Although they are all value types, they don't have a common parent that has any useful methods.

A simple example given here: you want to provide the user with several text boxes where he/she can enter a value that needs to be tested. This is very easy to do by just coding a different method for each value type like this:

C#
private void TestInt32(TextBox textBox, Label resultLabel)
{
    try
    {
        Int32 res = Convert.ToInt32(textBox.Text);
        resultLabel.Text = "Success!";
        resultLabel.BackColor = Color.Green;
    }
    catch
    {
        resultLabel.Text = "Failure!";
        resultLabel.BackColor = Color.Red;
    }
}
    
private void TestBool(TextBox textBox, Label resultLabel)
{
    try
    {
        Boolean res = Convert.ToBoolean(textBox.Text);
        resultLabel.Text = "Success!";
        resultLabel.BackColor = Color.Green;
    }
    catch
    {
        resultLabel.Text = "Failure!";
        resultLabel.BackColor = Color.Red;
    }
}

This is both annoying and repeating a lot of code to do the same. Unfortunately, Microsoft did not provide us with a way to write a generics class/method for the basic value types. This article shows a possible solution.

Using the Code

The example code shows a generics method for conversion of an object to a provided basic value type.

C#
public static T ToT<T>(object value)
{
    switch (Type.GetTypeCode(typeof(T)))
    {
        case TypeCode.Boolean:
            return (T)(object)Convert.ToBoolean(value);
        case TypeCode.Byte:
            return (T)(object)Convert.ToByte(value);
        case TypeCode.Char:
            return (T)(object)Convert.ToChar(value);
        case TypeCode.DateTime:
            return (T)(object)Convert.ToDateTime(value);
        case TypeCode.Decimal:
            return (T)(object)Convert.ToDecimal(value);
        case TypeCode.Double:
            return (T)(object)Convert.ToDouble(value);
        case TypeCode.Int16:
            return (T)(object)Convert.ToInt16(value);
        case TypeCode.Int32:
            return (T)(object)Convert.ToInt32(value);
        case TypeCode.Int64:
            return (T)(object)Convert.ToInt64(value);
        case TypeCode.Object:
            return (T)value;
        case TypeCode.SByte:
            return (T)(object)Convert.ToSByte(value);
        case TypeCode.Single:
            return (T)(object)Convert.ToSingle(value);
        case TypeCode.String:
            return (T)(object)Convert.ToString(value);
        case TypeCode.UInt16:
            return (T)(object)Convert.ToUInt16(value);
        case TypeCode.UInt32:
            return (T)(object)Convert.ToUInt32(value);
        case TypeCode.UInt64:
            return (T)(object)Convert.ToUInt64(value);
        case TypeCode.DBNull:
        case TypeCode.Empty:
        default:
            throw new ApplicationException("Unsupported generics type");
    }
}

The double conversion to object and then to T in every return is unfortunately unavoidable because Visual Studio cannot identify at compile time that the result of the conversion is of type T.

Thus a single method can be used to verify all our fields:

C#
private void Test<T>(TextBox textBox, Label resultLabel)
{
    try
    {
        T res = ConvertEx.ToT<T>(textBox.Text);
        resultLabel.Text = "Success!";
        resultLabel.BackColor = Color.Green;
    }
    catch
    {
        resultLabel.Text = "Failure!";
        resultLabel.BackColor = Color.Red;
    }
}
private void testButton_Click(object sender, EventArgs e)
{
    Test<Int32>(this.int32TextBox, this.int32ResultLabel);
    Test<Boolean>(this.boolTextBox, this.boolResultLabel);
    Test<Decimal>(this.decimalTextBox, this.decimalResultLabel);
}

Further Development

Conversion is not the only operation that one would need for basic value types. For example, general Parse or TryParse methods would be very helpful and are pretty easy to implement in the same way.

Gratitude

I would like to specially thank Dobby who helped me with the consideration of this method and helped me make it clearer and easier to understand.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Switzerland Switzerland
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralChangeType Pin
PIEBALDconsult17-Jun-10 17:21
mvePIEBALDconsult17-Jun-10 17:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.