2010-04-01 65 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