HI, 我有以下场景,我将尽力解释,如果这是一个愚蠢的问题,请提前预测。 我有两个接口(本例中没有任何内容)
public interface interfaceA {}
public interface interfaceB: interfaceA {}
和2个班级
public classA<interfaceA> {}
public classB: classA<interfaceB> { }
现在在其他地方我有一个接受泛型类型作为参数的方法:
public static void DoSomething( ClassA<interfaceB> p_val ) {}
好的,然后我在创建对象时使用这些类。
ClassB obj1 = new ClassB();
ClassA<interfaceA> obj2 = new ClassA<interfaceA>();
当我将obj1传递给DoSomething()时,一切都很好但是当我尝试将obj2传递给我的DoSomething()方法时,我得到一个编译错误,说它无法从interfaceA转换为interfaceB。
这种有意义,因为在我的方法中,泛型param类型是显式的interfaceB。但是,如果我希望该方法接受两种泛型类型(obj1和obj2),我该怎么办?希望这是有道理的。
答案 0 :(得分:6)
怎么样
public static void DoSomething<T>( ClassA<T> p_val)
{}
无论类型参数是什么,它都接受ClassA的任何实例。或者,如果您只想在ClassA<T>
为T
或其子类时接受InterfaceA
的实例,则可以执行以下操作:
public static void DoSomething<T>( ClassA<T> p_val) where T : InterfaceA
{}
答案 1 :(得分:4)
sepp2k和Jordão都可以解决您的问题。至于为什么(根据你的问题标题)...
的原因在.NET 4.0之前,covariance and contravariance在泛型中是不允许的 - 你试图使用逆变(从更广泛的基类到更窄的子类)。这就像为期望classA<object>
的方法指定classA<string>
。
无论ClassA
对interfaceB
做什么,您都无法保证obj2能够实现它,因为obj2 无法处理interfaceB
个实例(也不是隐含地,做它的消费者)。它仅适用于interfaceA
个实例。
如果您使用的是4.0,则可以通过接口和委托以有限的方式执行此操作。请参阅Covariance and Contravariance in Generics。
答案 2 :(得分:2)
这里有一个误解:
public class classA<interfaceA> {}
这不是interfaceA
,它是一个与interfaceA
同名的类型参数。试试这样,错误就有意义了:
public class classA<T> {}
也许这就是你真正想要的:
public class classA<T> where T : interfaceA {}
但如果没有sepp2k提出的更改,它仍然无法在您的示例中使用。
答案 3 :(得分:1)
最小的公共单位是接口A,所以尝试在DoSomthing方法中声明接口A param而不是B.