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
???? {
??? } }