sing 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
{
}
}
本文深入探讨了C#中泛型的协变(covariance)和逆变(contravariance)概念,通过示例解释了它们在接口和委托中的作用。逆变允许将派生类对象赋值给基类引用,而协变则允许使用更广泛的类型作为参数。同时,文章指出了这两种变异性在参数和返回值中的限制及其原因。
984

被折叠的 条评论
为什么被折叠?



