Variance变性
泛型的某个方面会让人感到奇怪,比如下面的代码是不合法的——
IList<string> strings = new List<string>();
IList<object> objects = strings;
第二个赋值是不允许的,因为strings和objects的元素类型并不一样。这样做有这充分的原因。如果允许那样写的话,你可能会写——
objects[0] = 5;
string s = strings[0];
这会允许将int插入strings列表中,然后将其作为string取出。这会破坏类型安全。
然而,对于某些接口来说上述情况并不会发生,尤其是不能将对象插入集合时。例如IEnumerable<T>就是这样的接口。如果改为——
IEnumerable<object> objects = strings;
这样就没法通过objects将错误类型的东西插入到strings中了,因为objects没有插入元素的方法。变性(variance)就是用于在这种能保证安全的情况下进行赋值的。结果就是很多之前让我们感到奇怪的情况现在可以工作了。
Covariance
协变性
在.NET 4.0中,IEnumerable<T>接口将会按照下面的方式进行定义——
public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
public interface IEnumerator<out T> : IEnumerator
{