好吧,这在 C# 4 中肯定不会得到支持。有一个基本问题:
List<Giraffe> giraffes = new List<Giraffe>();
giraffes.Add(new Giraffe());
List<Animal> animals = giraffes;
animals.Add(new Lion()); // Aargh!
保持长颈鹿的安全:对不安全的变异说不。
数组版本之所以有效,是因为数组确实支持引用类型变化,并带有执行时间检查。泛型的重点是提供编译时类型安全。
在 C# 4 中将支持安全泛型变体,但仅支持接口和委托。因此,您将能够:
Func<string> stringFactory = () => "always return this string";
Func<object> objectFactory = stringFactory; // Safe, allowed in C# 4
Func<out T>
是协变的,T
因为T
仅用于输出位置。比较 which 与Action<in T>
which 是逆变的,T
因为T
仅用于那里的输入位置,使其安全:
Action<object> objectAction = x => Console.WriteLine(x.GetHashCode());
Action<string> stringAction = objectAction; // Safe, allowed in C# 4
IEnumerable<out T>
正如其他人指出的那样,它也是协变的,这在 C# 4 中是正确的:
IEnumerable<Animal> animals = new List<Giraffe>();
// Can't add a Lion to animals, as `IEnumerable<out T>` is a read-only interface.
就您在 C# 2 中的情况解决此问题而言,您是否需要维护一个列表,或者您是否愿意创建一个新列表?如果这是可以接受的,List<T>.ConvertAll
是你的朋友。