65.9K
CodeProject 正在变化。 阅读更多。
Home

基本类型的泛型转换器

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.36/5 (8投票s)

2010年6月17日

CPOL

2分钟阅读

viewsIcon

24033

downloadIcon

119

一个将对象转换为基本类型的泛型方法。

Screenshot.jpg

引言

本文介绍了一种创建泛型转换方法的方法,该方法可用于基本类型(boolintbyte 等)。

背景

在某些情况下,您希望为几种不同的数据类型创建泛型处理,这些数据类型非常相似,但没有共同的父类或不继承公共接口。这在表示值类型的基本 .NET 类(boolintbyte 等)中经常发生。虽然它们都是值类型,但它们没有具有任何有用方法的公共父类。

一个简单的例子如下:您希望为用户提供几个文本框,用户可以在其中输入需要进行测试的值。只需为每个值类型编写不同的方法即可轻松完成此操作

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;
    }
}

这既令人烦恼,又会重复很多代码来做同样的事情。不幸的是,Microsoft 没有为基本值类型提供编写泛型类/方法的方法。本文展示了一种可能的解决方案。

Using the Code

示例代码显示了一个将对象转换为提供的基本值类型的泛型方法。

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");
    }
}

由于 Visual Studio 在编译时无法识别转换结果的类型为 T,因此每次返回都进行两次转换为 object,然后再转换为 T,不幸的是,这是不可避免的。

因此,可以使用一个方法来验证我们所有的字段

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);
}

进一步开发

转换不仅仅是值类型所需的操作。例如,通用的 ParseTryParse 方法将非常有用,并且可以以相同的方式轻松实现。

感谢

我特别感谢 Dobby,他帮助我考虑这种方法,并帮助我使其更清晰易懂。

© . All rights reserved.