C#方差问题:分配表<衍生GT;如表<基地以及GT; [英] C# variance problem: Assigning List<Derived> as List<Base>

查看:108
本文介绍了C#方差问题:分配表<衍生GT;如表<基地以及GT;的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请看下面的例子(部分从<一个取href=\"http://blogs.msdn.com/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two-array-covariance.aspx\">MSDN博客):

Look at the following example (partially taken from MSDN Blog):

class Animal { }
class Giraffe : Animal { }

static void Main(string[] args)
{
    // Array assignment works, but...
    Animal[] animals = new Giraffe[10]; 

    // implicit...
    List<Animal> animalsList = new List<Giraffe>();

    // ...and explicit casting fails
    List<Animal> animalsList2 = (List<Animal>) new List<Giraffe>();
}

这是一个协方差问题?这是否会在未来的C#版本中支持以及是否有任何变通巧(仅使用.NET 2.0)?

Is this a covariance problem? Will this be supported in the future C# release and are there any clever workarounds (using only .NET 2.0)?

推荐答案

嗯,这肯定不会在C#中支持4有一个根本性的问题:

Well this certainly won't be supported in C# 4. There's a fundamental problem:

List<Giraffe> giraffes = new List<Giraffe>();
giraffes.Add(new Giraffe());
List<Animal> animals = giraffes;
animals.Add(new Lion()); // Aargh!

请长颈鹿安全:只说不不安全的差异

Keep giraffes safe: just say no to unsafe variance.

该阵列版本的作品,因为阵列的的支持引用类型差异,随着执行时间检查。泛型的一点是要提供的编译时间的类型安全。

The array version works because arrays do support reference type variance, with execution time checking. The point of generics is to provide compile-time type safety.

在C#4将有支持的安全的通用方差,但只有接口和委托。所以,你可以做:

In C# 4 there will be support for safe generic variance, but only for interfaces and delegates. So you'll be able to do:

Func<string> stringFactory = () => "always return this string";
Func<object> objectFactory = stringFactory; // Safe, allowed in C# 4

Func键&LT;出T&GT; 的在 T ,因为 T 仅在输出位置使用。相比之下,与动作&LT;在T&GT; 这是逆变的在 T ,因为 T 仅在输入位置使用存在,使得这种安全的:

Func<out T> is covariant in T because T is only used in an output position. Compare that with Action<in T> which is contravariant in T because T is only used in an input position there, making this safe:

Action<object> objectAction = x => Console.WriteLine(x.GetHashCode());
Action<string> stringAction = objectAction; // Safe, allowed in C# 4

的IEnumerable&LT;出T&GT; 是协变的为好,使这条正确的C#4,如被别人指出的:

IEnumerable<out T> is covariant as well, making this correct in C# 4, as pointed out by others:

IEnumerable<Animal> animals = new List<Giraffe>();
// Can't add a Lion to animals, as `IEnumerable<out T>` is a read-only interface.

在C#2解决这个工作你的情况而言,你需要保持的有一个列表,或者你会很乐意创建一个新的列表?如果这是可以接受的,列表&LT; T&GT; .ConvertAll 是你的朋友。

In terms of working around this in your situation in C# 2, do you need to maintain one list, or would you be happy creating a new list? If that's acceptable, List<T>.ConvertAll is your friend.

这篇关于C#方差问题:分配表&LT;衍生GT;如表&LT;基地以及GT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆