C#通用类型转换异常

6

在使用泛型时,我遇到了一个奇怪的转换问题。尽管明显可以将int转换为double,但以下代码将抛出InvalidCastException异常。有谁能解释这种行为以及如何绕过它吗?

public class TestClass<T>
{
    public T Cast(object o)
    {
        return (T)o;
    }
}

public void Main()
{
    TestClass<double> w = new TestClass<double>();
    double x = w.Cast(10);
}

编辑:

既然我已经在 .net 4.0 的领域里了,我已经将它改为使用“动态”而不是“对象”,一切都如预期般工作。感谢所有准确且快速的回复。

7个回答

9

但是一个 object 无法转换为 double 参数 o 接受的是一个 object,而不是一个 int

例如,以下代码会因为 InvalidCastException 而失败:

 object o = 1000;
 double x = (double)o;

2
吹毛求疵: 如果该“object”是一个装箱的“double”,那么它可以被转换为“double”。 - LukeH
确实可以。虽然在示例代码中没有这种情况,所以我没有考虑包含它,但是值得一提。 - Cody Gray
谢谢,显然我没有考虑到将其装箱为对象。 - Andrew Hanlon

6

您可以使用TypeConverter来转换变量。

        public class TestClass<T>
        {
            public T Cast(object o)
            {
                TypeConverter converter = TypeDescriptor.GetConverter(o);
                if (converter.CanConvertTo(typeof(T)))
                {
                   var result = converter.ConvertTo(o, typeof(T));
                   return (T)result;
                }

                throw new InvalidCastException(
                      string.Format("Cannot convert from {0} to {1}", o.GetType().Name, typeof(T).Name));
            }
        }

谢谢,我对于变量类型转换没有想得很清楚。感谢您的回复,但是我必须把分数给第一个发帖者... - Andrew Hanlon

1

Cast中的参数'o'是装箱的。显然,您无法将装箱的int强制转换为未装箱的double。请参见此处

如果您知道在Cast函数内部它是一个int,您可以执行以下操作:

return (double)((int)o);

我不知道未知类型的情况。正在检查。

编辑:将T更改为double


哦,不行。当将该代码完全插入到“Cast”函数中时,它无法编译。您无法将“int”转换为“T”。 - Cody Gray
Cody,嗯,是的。我只是想表明理论上如果o被解包成int,转换就会成功。现在已经修复了。 - sinelaw

1

这会生效

        object y = 10;
        Double v = (int) y;

这将不会

        object y = 10;
        Double v = y;

因为它必须显式地转换。


谢谢,我对于变量类型转换没有想得很清楚。感谢您的回复,但是我必须把分数给第一个发帖者... - Andrew Hanlon

0

你可以通过以下方式绕过它:

public class TestClass<T>
{
    public T Cast<T2>(T2 o)
    {
        return (T)o;
    }
}

希望这可以推断出您正在使用int并允许该情况(这里没有测试的机会)。尽管它不能防止您放置其他无法正确转换的内容。

1
这将在编译时失败,因为将任意的 T2 强制转换为任意的 T 是不可能的。 - LukeH
1
你为什么会希望出现运行时错误呢?在编译时捕获错误似乎对所有人来说都是更好的选择。 - Cody Gray

0
 public T Cast(object o)
 {
     return (T)Convert.ChangeType(o, typeof (T));

 }

我不确定为什么。


1
原因是此方法仅包装对适当的 IConvertible 方法的调用。如果类型未实现 IConvertible 接口,则会引发 InvalidCastException - Cody Gray

-1
我猜这是因为int不能被强制转换为double,但是可以进行显式转换为double。这必须在类型上定义。由于您的Cast对象不知道给定类型是否具有此转换,它尝试进行基本转换并失败了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接