C#:使用泛型类的非泛型类undefined

时间:2011-02-27 13:57:59

标签: c# generics inheritance

我有一个通用接口

public interface TheInterface<T> where T : IObject

我还有一个这个界面与

配合使用的对象类
public class SomeObject : IObject

然后我有一个实现接口的类

public class ClassThatWorksWithSomeObject : TheInterface<SomeObject>

这一切都运作良好。稍后我会添加一个与TheInterface类一起使用的类,与他使用的IObject版本无关。

public class IDoStuffToInterface
{
    public IDoStuffToInterface(TheInterface<IObject> interface)
    {
         //bla bla
    }
}

问题是我无法在那里传递ClassThatWorksWithSomeObject,即使它继承自intreface并且它的通用对象继承自IObject

我想在某些情况下如果确实可能有害,但我想不出任何一种情况。

有没有办法更好地做到这一点?

5 个答案:

答案 0 :(得分:1)

我不知道详细的实现,你可以尝试:

public interface TheInterface<out T> where T : IObject 

如果您使用的是C#4.0

答案 1 :(得分:1)

我认为您正在做的事情应该有效,但您可能需要使用covariance and contravariance keywords

答案 2 :(得分:1)

您需要定义TheInterface协变,以便接受更广泛类型的IObject

public interface TheInterface<out T> where T : IObject

答案 3 :(得分:1)

你应该能够通过将接口类型标记为逆变来在C#4.0中执行此操作,但我认为你也可以通过使IDoStuffInterface也是通用的来解决这个问题。

public class IDoStuffToInterface<T> where T : IObject
{
    public IDoStuffToInterface(TheInterface<T> interface)
    {
         //bla bla
    }
}

由于SomeObject符合T和ClassThatWorksWithSomeObject实施TheInterface<SomeObject>的条件,因此它可以作为参数接受。

答案 4 :(得分:1)

我看到tvanfosson提到的另一种方法是让你的IDoStuffToInterface类通用。如果(如示例中所示)将TheInterface传递给构造函数并且(可能)存储在类中,那么这也可以很好地工作。

但是,如果它只是一个使用TheInterface的函数(甚至构造函数)而它没有存储在类中,那么将函数本身设置为通用可能会更好并让班上独自一人。例如:

public class IDoStuffToInterface
{
    public void DoSomething<T>(TheInterface<T> theInterface) where T : IObject
    {
        //bla bla
    }
}

这将允许您执行以下操作:

ClassThatWorksWithSomeObject myObject = new ClassThatWorksWithSomeObject();
IDoStuffToInterface actor = new IDoStuffToInterface();
actor.DoSomething(myObject);

编译时没有任何问题,因为编译器能够通过推断告诉您实际上正在调用

actor.DoSomething<SomeObject>(myObject);

现在,我认为如果您控制接口定义,使用协方差仍然是最佳选择。但是,当你在界面中没有这种程度的控制时,我想把它添加为另一种选择。