泛型的逆变与斜变
using System;
using System.Collections.Generic;namespace CCTest
{
class Program
{
static void Main(string[] args)
{
Bird bird1 = new Bird();
Bird bird2 = new Sparrow();//逆变斜变只作用于接口和委托
List<Bird> birdlist1 = new List<Bird>();
//List<Bird> 是个类 List<Sparrow>()也是一个类 没父子关系 所以语法报错
List<Bird> birdlist2 = new List<Sparrow>();
//斜变效果: 就是让右边可以用子类 让泛型用起来更方便
IEnumerable<Bird> birdlist3 = new List<Bird>();
IEnumerable<Bird> birdlist4 = new List<Sparrow>();//out 斜变 只能是返回结果 不能做参数
ICustomerListOut<Bird> birdlist5 = new CustomerListOut<Sparrow>();//为什么T可以是返回值?
//接口要求返回一个 Bird 其实现类返回一个 Sparrow , Sparrow继承Bird 所以ok;//为什么T不可以是参数?
//可以想象一下, 假设我们这样定义
// ICustomerListOut<Bird> birdlist5 = new CustomerListOut<Sparrow>();
//在调用 birdlist5.Show 方法时 其实现类要求传入的是 Sparrow
//简单讲: 接口定义的是父类, 其实现类要求传入一个子类 所以用不成{
//逆变: 就是让右边可以用父类, 让泛型用起来更方便
//in 逆变 只能做参数 不能是返回结果
ICustomerListIn<Sparrow> birdlist6 = new CustomerListIn<Bird>();
birdlist6.Show(new Sparrow());//为什么T可以是参数?
//接口定义一个方法,其传入参数是Sparrow ,其实现类调用Show方法 传入Bird, Sparrow时bird 所以可以//为什么T不可以是返回值?
//接口要求返回 Sparrow ,其实现类返回bird Bird不是Sparrow 所以不行
}
}
}interface ICustomerListIn<in T>
{
void Show(T t);
//T Get();
}
class CustomerListIn<T> : ICustomerListIn<T>
{
public void Show(T t)
{
}
}
interface ICustomerListOut<out T>
{
T Get();
//void Show(T t);
}class CustomerListOut<T> : ICustomerListOut<T>
{
public T Get()
{
return default(T);
}
}
class Bird
{}
class Sparrow: Bird
{}
}