【问题标题】:C# 4.0 RC, Silverlight 4.0 RC CovarianceC# 4.0 RC、Silverlight 4.0 RC 协方差
【发布时间】:2010-04-01 06:26:13
【问题描述】:

我正在尝试使用 C# 4.0 开发 Silverlight 4 应用程序。 我有这样一个案例:

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) 是否支持协方差?

【问题讨论】:

  • 由于下面的答案,我设法重构了我的 Foo 类型,以便让它实现一个定义协方差的接口。

标签: c# silverlight c#-4.0 covariance


【解决方案1】:

要表明接口或委托的泛型类型参数在T 中是协变的,您需要提供out 关键字。

但是,目前这对于类是不可能的。我建议创建一个带有协变泛型类型参数的接口,并让你的类实现它。

关于 Silverlight 4 中的协方差支持:在测试版中不支持,我需要检查他们是否在候选发布版中实现了它。编辑:显然是这样。

编辑2: 由于 BCL 中的某些类型没有设置适当的泛型类型修饰符(IEnumerable&lt;T&gt;Action&lt;T&gt;、@ 987654327@, ...)。

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

【讨论】:

  • 您确定它在 4.0 RTM 中吗?我在那里看不到。例如,IEnumerable 上的类型参数似乎没有 out 修饰符。
  • SL4 编译器确实支持接口和委托上的inout 修饰符,但是您是正确的,BCL 中应该具有修饰符的类型不支持。此问题将在即将发布的 SL 版本 5 (10rem.net/blog/2011/09/04/…) 中解决
【解决方案2】:

仅接口和委托支持协方差:

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-接口上的关键字Foo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多