2011-02-27 131 views
1

我有一个通用接口C#:使用泛型类非泛型类不确定

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继承。

我想有些情况下,如果它可能会伤害,但我想不出任何。

有没有办法做得更好?

+0

在C#类*实现*接口中,它们不从它们继承。 – 2011-02-27 14:01:55

+0

真的,我的一个小错误。 – 2011-02-27 14:16:13

+0

如果TheInterface 是一个抽象类而不是一个接口,那么Co/contra-variance将不起作用。 – 2011-02-27 14:24:56

回答

1

我不知道细节impelmentation,你可以尝试:

public interface TheInterface<out T> where T : IObject 

,如果你使用的是C#4.0

+0

你们大部分人都回答了相同的答案,我给你们所有的赞成,但我想你会在第一时间得到正确的答案。使用这种公约有什么明显的缺点。 – 2011-02-27 14:22:04

+0

@Vals:没有*缺点*,如果您的界面中的“T”用作输入,则不能使用'out'关键字。 'void Add(T item)'。 – 2011-02-27 14:27:50

+0

@Vals:而且,如果使用'T'作为返回值,则不能使用'in'关键字。 'T Get(string key)'。 – 2011-02-27 14:29:33

1

你需要让TheInterface协变的,你的定义,使其接受更广泛类型的IObject

public interface TheInterface<out T> where T : IObject 
1

您应该能够通过标记接口类型为逆变为此在C#4.0,但我想你也可以通过使IDoStuffInterface通用来解决这个问题。

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

由于SomeObject资格T和ClassThatWorksWithSomeObject实现TheInterface<SomeObject>,它应该是作为一个参数是可接受的。

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); 

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