2011-11-02 67 views
1

我有一个泛型类使用另一个类,它返回时需要知道什么样的初始类“拥有”它 - 这会导致问题;)让我举个例子:接口和泛型的双向引用

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(编译但在运行时失败)。我试图用各种方式调整代码,但我还没有找到一个可行的实现...

希望你看到我想要做的事情,也许你甚至看到我如何实现这一点; - )

回答

4

您可以在构造函数中显式类型转换的组合解决这个问题,随着C#4.0泛型参数协方差支持。

首先,你需要在Foo<T>构造插入投:

_bar = new T {Foo = (IFoo<IBar>)this}; 

只是这样做是不够的,虽然。你的约束条件是T : new()意味着T需要成为一个具体的类。因此,IFoo<T>将永远不会完全是IFoo<IBar>。但是,如果你指定为IBar<T>泛型参数T是协变,然后从IFoo<Bar>IFoo<IBar>投将成为法律:

public interface IFoo<out T> 

out关键字指定的参数是协变(这基本上意味着“这个参数会只能用方法输出,不要输入“)

This MSDN article提供了关于协方差和逆变的更多细节。

+0

这没有把戏!修复了一个问题并且学到了新的东西不错:)谢谢! –

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

} 
+0

工作了一个魅力:) –