基础【泛型】-----(协变,逆变1)------(转)

“协变”是指能够使用与原始指定的派生类型相比,派生程度更大的类型。

“逆变”则是指能够使用派生程度更小的类型。

解释的很正确,大致就是这样,不过不够直白。

直白的理解:

“协变”->”和谐的变”->”很自然的变化”->string->object :协变。

“逆变”->”逆常的变”->”不正常的变化”->object->string 逆变。

上面是个人对协变和逆变的理解,比起记住那些派生,类型,原始指定,更大,更小之类的词语,个人认为要容易点。

实例:两个类

1 // 父类:动物
2     public class Animal
3     { }
4 
5     // 子类:狗
6     public class Dog : Animal
7     { }

1、Dog继承Animal ,可以Animal animal = dog; 那么List<Animal> listAniaml = listDog;如何实现呢

 1 public static void MainClass()
 2         {
 3 
 4             Dog dog = new Dog();
 5             // Dog继承自Animal,会隐式的转变为Animal;
 6             // 子类对象可以创建为它的父类对象(自动转换的)
 7             Animal animal = dog;
 8 
 9             List<Dog> listDog = new List<Dog>();
10             // List<Dog> 不继承List<Animal> ,会出错
11             //List<Animal> listAniaml = listDog;
12 
13             // 方法一:
14             List<Animal> lstAnimal2 = listDog.Select(d => (Animal)d).ToList();
15 
16             // 方法二:
17             IEnumerable<Dog> someDogs = new List<Dog>();
18             IEnumerable<Animal> someAnimals = someDogs;
19         }

其中方法二:IEnumerable<T> (T为协变)

  因为T只能做结果返回,所以T不会被修改,编译器就可以推断下面的语句强制转换合法,所以可以转换。

 

2、一个子类Dog可以创建成为它的父类Animal 对象,那如果实现一个父类创建成为它的一个子类对象呢?

因为协变和逆变的英文太复杂了,并没有体现协变和逆变的不同,但是out 和 in 却很直白。out: 输出(作为结果),in:输入(作为参数)。所以如果有一个泛型参数标记为out,则代表它是用来输出的,只能作为结果返回,而如果有一个泛型参数标记为in,则代表它是用来输入的,也就是它只能作为参数。

 1 public interface IMyList<in T>
 2     {
 3         void ChangeT(T t);
 4     }
 5 
 6     public class MyList<T> : IMyList<T>
 7     {
 8         public void ChangeT(T t)
 9         {
10             //Change T  
11         }
12     }
13 
14     // 编译成功,因为in代表了逆变,所以可以编译成功!
15     IMyList<Animal> myAnimals = new MyList<Animal>();
16     IMyList<Dog> myDogs = myAnimals;

 

posted @ 2013-10-29 17:19  行进  阅读(130)  评论(0编辑  收藏  举报