使用as关键字的接口异常whitout强制转换

时间:2013-11-20 17:32:49

标签: c# interface

我尝试创建一个泛型类,它接收基于接口的泛型参数,代码是异常

所以我测试了,我有以下

interface InterfaceA { }
interface InterfaceB<T> where T:InterfaceA { }
class ClassA : InterfaceA { }
class ClassB : InterfaceB<ClassA> { }

基本测试

InterfaceB<InterfaceA> my_object_1 = new ClassB(); // Not Working (Compile error)
InterfaceB<InterfaceA> my_object_2 = (InterfaceB<InterfaceA>)new ClassB(); // Not Working (Throw Exception)
InterfaceB<InterfaceA> my_object_3 = new ClassB() as InterfaceB<InterfaceA>; // Working but still null

有人可以解释为什么my_object_1,my_object_2和my_object_3出现问题?

1 个答案:

答案 0 :(得分:5)

new ClassB() as InterfaceB<InterfaceA>确实没有抛出异常,但它确实返回null,当它无法投射时会返回what as does。这是因为ClassB无法用作InterfaceB<InterfaceA>,无论您如何尝试投射它。

隐式可用作InterfaceB<InterfaceA>,但是,如果您将out放在T之前:

interface InterfaceB<out T> where T:InterfaceA { }

这会产生T covariant,这意味着,例如InterfaceB<ClassA>可以用作InterfaceB<InterfaceA>(但反之亦然)。

如果T无法协变,编译器将会出错,因为您将T作为输入。使用此类界面时,您无法在逻辑上将ClassB用作InterfaceB<InterfaceA>,原因与使用List<string>作为IList<object>无效的原因相同:你可以尝试做一些不可能的事情,比如将非字符串对象添加到字符串列表中。