为什么我不能使用与继承接口相同的泛型类型?

时间:2010-07-01 14:22:22

标签: c#

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),我该怎么办?希望这是有道理的。

4 个答案:

答案 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)

sepp2kJordão都可以解决您的问题。至于为什么(根据你的问题标题)...

的原因

在.NET 4.0之前,covariance and contravariance在泛型中是不允许的 - 你试图使用逆变(从更广泛的基类到更窄的子类)。这就像为期望classA<object>的方法指定classA<string>

无论ClassAinterfaceB做什么,您都无法保证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.