2

来自第三方应用程序的对象值提供了一个正确但键入错误的值。我正在尝试在我正在创建的通用方法中将这个对象值输入到我选择的类型中。我已经模拟了一个示例来演示该问题。

static void Main(string[] args)
{
    decimal d = 1; // this can't be changed
    var v = Method<int>(d); // what I'm trying to do
}

//the code in this method can be changed
static T Method<T>(object input)
{
    T output = default(T);

    //causes InvalidCastException
    output = (T)input;

    return output;
}

如您所见,值“1”是一个有效的整数,但是当第三方应用程序将其键入为小数时,当尝试将其转换为整数时,它会失败。如何更改通用方法以使其不会因这种情况而崩溃?

4

3 回答 3

2

替换output = (T)input;为:

output = (T)Convert.ChangeType(input, typeof(T));
于 2013-02-01T17:18:19.863 回答
1

尝试这样的事情:

static T Method<T>(object input)
{
    T output = default(T);

    var t = input.GetType();
    TypeConverter tc = TypeDescriptor.GetConverter(t);
    output = (T)tc.ConvertTo(input, typeof(T));

    return output;
}

显然,您需要添加一些错误检查以确保类型兼容——查看 TypeConverter 上的方法。

您需要添加一个using System.ComponentModel;

于 2013-02-01T17:18:23.150 回答
1

“铸造”和“转换”是两个非常不同的东西。不幸的是,在某些情况下,C# 中的语法是相同的,因此可能会混淆主题。

input只能转换为 a decimal,因为它确实是这样。您可以将 a 转换为 a decimalint但不能转换,而object这恰好包含 adecimal到 a int

所以如果你这样做:

static int ToInt(object input)
{
    return (int)(decimal)input;
}

然后它将起作用。

如果你想处理有一个转换运算符的一般情况inputT那么你就很不走运了。这些转换是编译时机制,而不是运行时机制。

于 2013-02-01T17:19:18.753 回答