我尝试创建一个泛型类,它接收基于接口的泛型参数,代码是异常
所以我测试了,我有以下
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出现问题?
答案 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>
无效的原因相同:你可以尝试做一些不可能的事情,比如将非字符串对象添加到字符串列表中。