2010-04-01 75 views
0

我想用C#4.0開發Silverlight 4應用程序。 我有這樣一個案例:C#4.0 RC,Silverlight 4.0 RC協方差

public class Foo<T> : IEnumerable<T> 
{ 
    .... 
} 

在別處:

public class MyBaseType : MyInterface 
{ 
    ... 
} 

和使用我在哪裏有問題:

Foo<MyBaseType> aBunchOfStuff = new Foo<MyBaseType>(); 
Foo<MyInterface> moreGeneralStuff = myListOFStuff; 

現在,我相信這是在C#3.0,因爲不可能泛型類型是「不變的」。然而,我認爲在C#4.0中通過泛型技術的新協變可以實現這一點。

據我所知,在C#4.0中,許多常用接口(如IEnumerable)已被修改以支持差異。在這種情況下,我的Foo類需要什麼特別才能變得協變?

並且在Silverlight 4(RC)中支持協變?

+0

由於下面我manged重構我的Foo類型不同,以擁有它實現一個接口,在其上定義的協方差的答案。 – 2010-04-02 22:06:55

回答

1

協方差僅支持接口和委託:

public interface Foo<out T> { } 
public class Bar<T> : Foo<T> { } 

interface MyInterface { } 
public class MyBase : MyInterface { } 

Foo<MyBase> a = new Bar<MyBase>(); 
Foo<MyInterface> b = a; 

重要的是out -Keyword在接口Foo

+0

謝謝,我看到我用界面做的錯誤... – 2010-04-01 07:32:30

4

要指示接口或代理的通用類型參數在T中是協變的,您需要提供out關鍵字。

但是這對於類目前是不可能的。我建議使用協變泛型類型參數創建一個接口,並讓您的類實現它。

至於Silverlight 4中的協變支持:在測試版中它不被支持,我需要檢查它們是否在候選版本中實現了它。編輯:顯然是。

EDIT2: 可能會有一些混亂SL4是否真正支持合作和逆變的接口和委託,由於一些在BCL的類型不具有相應的泛型類型修飾符設置(IEnumerable<T>Action<T>,Func<T>,...)。

的Silverlight 5解決這些問題:http://10rem.net/blog/2011/09/04/the-big-list-of-whats-new-or-improved-in-silverlight-5

的SL4編譯但是支持inout修飾。下面的編譯和按預期工作:

interface IFoo<out T> 
{ 
    T Bar { get; } 
} 
interface IBar<in T> 
{ 
    void Add(T value); 
} 
delegate void ContravariantAction<in T>(T value); 
delegate T CovariantFunc<out T>(); 
+0

謝謝,有用的答案 – 2010-04-02 22:05:29

+0

你確定它是在4.0 RTM?我在那裏看不到它。例如,似乎沒有對'IEnumerable'類型參數的'out'修飾符。 – 2011-10-11 10:08:41

+0

SL4編譯器確實支持接口和委託中的「in」和「out」修飾符,但是您應該修改器的BCL中的類型不對。這個問題將在SL即將發佈的第5版中得到解決(http:// 10rem。淨/博客/ 2011/09/04 /的-大列表的 - 什麼 - 新或改善的功能於Silverlight的5) – 2011-10-12 11:31:10