简体   繁体   English

C#通用铸造异常

[英]C# generic casting exception

I have run into an odd casting issue while using generics. 我在使用泛型时遇到了一个奇怪的转换问题。 The following code will throw an InvalidCastException even though clearly an int can be cast to a double . 以下代码将抛出InvalidCastException即使显然int可以InvalidCastExceptiondouble Can anyone explain this behaviour and how to bypass it? 谁能解释这种行为以及如何绕过它?

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

Edit: 编辑:

Since I am in .net 4.0 land anyway I have changed it to use 'dynamic' instead of 'object' and everything works as expected. 因为我在.net 4.0土地上无论如何我改变它使用'动态'而不是'对象',一切都按预期工作。 Appreciate all the spot-on and quick replies. 欣赏所有现场和快速回复。

But an object can't be cast to a double . 但是一个object不能被强制转换为double The o parameter takes an object , not an int . o参数接受一个object ,而不是int

For example, the following code fails with an InvalidCastException : 例如,以下代码失败并出现InvalidCastException

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

You can use TypeConverter to convert variables 您可以使用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));
            }
        }

The parameter 'o' in Cast is boxed. Cast中的参数“o”已装箱。 You can't cast a boxed int to an unboxed double, apparently. 显然,你不能将盒装int强制转换为未装箱的双精度型。 See here . 看到这里

If you'd known it was an int inside the Cast function you could do: 如果您知道它是Cast函数中的int,您可以这样做:

return (double)((int)o);

I don't know about the case of an unknown type. 我不知道一个未知类型的情况。 Checking. 检查。

EDIT: change T to double 编辑:将T改为double

This would work 这会奏效

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

this will not 这不会

        object y = 10;
        Double v = y;

because it has to be casted explicitly. 因为它必须明确地铸造。

You could bypass it by doing: 您可以通过以下方式绕过它:

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

Which should hopefully (no chance to test here) infer that you're using an int and allow the case. 应该希望(没有机会在这里测试)推断你正在使用int并允许这种情况。 Although it doesn't prevent you putting other things that can't be cast properly in. 虽然它不会阻止你放置其他无法正确投射的东西。

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

 }

I am not sure why though. 我不知道为什么。

I'm guessing it's because an int can't be casted to a double, but there is an explicit conversion to a double. 我猜这是因为,int不能被浇铸为双,但有一个显式转换为双。 Which has to be defined on a type. 必须在类型上定义。 As your Cast object doesn't know whether a given type will have this conversion it tries a basic cast and fails. 由于您的Cast对象不知道给定类型是否具有此转换,因此它会尝试基本强制转换并失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM