我有一个使用泛型的类,它使用另一个类,反过来需要知道初始类的哪个实例“拥有”它 - 这会导致问题;)让我举一个例子:
public interface IFoo<T>
{
}
public interface IBar
{
IFoo<IBar> Foo { get; set; }
}
public class Foo<T> : IFoo<T> where T : IBar, new()
{
private readonly T _bar;
public Foo()
{
_bar = new T {Foo = this};
}
}
class Bar : IBar
{
public IFoo<IBar> Foo { get; set; }
}
这不起作用Foo =这不起作用 - 即使我尝试将其转换为IFoo(编译但在运行时失败)。我试图以各种方式调整代码,但我没有找到一个有效的实现......
希望你能看到我想要做的事情,也许你甚至可以看到我能做到这一点; - )
答案 0 :(得分:4)
您可以使用构造函数中的显式强制转换以及c#4.0对泛型参数协方差的支持来解决此问题。
首先,您需要在Foo<T>
构造函数中插入一个强制转换:
_bar = new T {Foo = (IFoo<IBar>)this};
但这样做还不够。 T : new()
意味着T
需要成为具体类的约束。因此,IFoo<T>
永远不会完全IFoo<IBar>
。但是,如果您指定T
的通用参数IBar<T>
是协变的,则从IFoo<Bar>
到IFoo<IBar>
的强制转换将变为合法:
public interface IFoo<out T>
out
关键字指定参数是协变的(这实际上意味着“此参数将仅由方法输出,从不输入。”)
This MSDN article提供了有关协方差和逆变的更多详细信息。
答案 1 :(得分:2)
将T
IFoo
类型参数声明为协变可以解决您的问题吗?
此代码应该允许您执行您正在尝试的操作:
public interface IFoo<out T> {
}
public interface IBar {
IFoo<IBar> Foo { get; set; }
}
public class Foo<T> : IFoo<T> where T : IBar, new() {
private readonly T _bar;
public Foo() {
_bar = new T { Foo = (IFoo<IBar>)this };
}
}
class Bar : IBar {
public IFoo<IBar> Foo { get; set; }
}
public static class Program {
public static void Main(params string[] args) {
Bar b = new Bar();
Foo<Bar> f = new Foo<Bar>();
}
}