2011-11-02 66 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

工作了一個魅力:) –