显式转换泛型类型参数的任何界面 [英] explicitly cast generic type parameters to any interface

查看:150
本文介绍了显式转换泛型类型参数的任何界面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

泛型常见问题解答:最佳实践说:

编译器将让您显式转换泛型类型参数的任何接口,而不是一类:

The compiler will let you explicitly cast generic type parameters to any interface, but not to a class:

interface ISomeInterface
{...}
class SomeClass
{...}
class MyClass<T> 
{
   void SomeMethod(T t)
   {
      ISomeInterface obj1 = (ISomeInterface)t;//Compiles
      SomeClass      obj2 = (SomeClass)t;     //Does not compile
   }
}

我看到不限于合​​理的为,类和接口,除非类/接口没有指定为约束类型。

I see limitation reasonable for both, classes and interfaces, unless the class/interface is not specified as constraint type.

那么,为什么这样的行为,为什么它是允许的接口?

So why such behavior, why it is allowed for interfaces ?

推荐答案

我相信这是因为剧组到 SomeClass的可根据什么转换意味着许多东西都可用,而投地 ISomeInterface 只能是一个参考转换或装箱转换。

I believe this is because the cast to SomeClass can mean any number of things depending on what conversions are available, whereas the cast to ISomeInterface can only be a reference conversion or a boxing conversion.

选项:


  • 演员到第一个对象:

  • Cast to object first:

SomeClass obj2 = (SomeClass) (object) t;


  • 使用而不是:

    SomeClass obj2 = t as SomeClass;
    


  • 显然,在第二种情况下,你还需要的情况下,请稍后执行无效检查 T 终止的的一个 SomeClass的

    Obviously in the second case you would also need to perform a nullity check afterwards in case t is not a SomeClass.

    编辑:推理为此在C#4规范第6.2.7所示:

    The reasoning for this is given in section 6.2.7 of the C# 4 specification:

    上面规则不允许从不受约束的类型参数到非接口类型,这可能是令人惊讶的直接显式转换。这样做的原因法则是prevent混乱,使这种转换的语义清晰。例如,请考虑下面的声明:

    The above rules do not permit a direct explicit conversion from an unconstrained type parameter to a non-interface type, which might be surprising. The reason for this rule is to prevent confusion and make the semantics of such conversions clear. For example, consider the following declaration:

    class X<T>
    {
        public static long F(T t) {
            return (long)t; // Error 
        }
    } 
    

    如果T的直接显式转换为int被允许,人们可能很容易想到的是 X&LT; INT&GT; .F(7)将返回7L。但是,它不会,因为当类型是已知的数字在结合时的标准数字转换只考虑。为了使语义清楚,上面的例子而必须被写成:

    If the direct explicit conversion of t to int were permitted, one might easily expect that X<int>.F(7) would return 7L. However, it would not, because the standard numeric conversions are only considered when the types are known to be numeric at binding-time. In order to make the semantics clear, the above example must instead be written:

    class X<T>
    {
        public static long F(T t) {
            return (long)(object)t; // Ok, but will only work when T is long
        }
    }
    

    这code现在可以编译,但执行 X&LT; INT&GT; .F(7)然后将引发在运行时异常,因为装箱的int不能直接转换为长

    This code will now compile but executing X<int>.F(7) would then throw an exception at run-time, since a boxed int cannot be converted directly to a long.

    这篇关于显式转换泛型类型参数的任何界面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆