其实就是和强转的意思差不多 只不过out 和 in已经提前强转了,我是这么理解的
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
#region 协变和逆变
Console.WriteLine("-----------------协变和逆变-------------------");
People people = new People();
People people1 = new Teacher();//Teacher是People的子类,可以继承
Teacher teacher = new Teacher();
List<People> peoples = new List<People>();
//[1]其实从现实中理解,应该是对的,但是是两个不同的类型,List<People>和List<Teacher>不是一个类型,不成立
//List<People> peoples1 = new List<Teacher>();
//所以其实这个是语法规则不支持,net2.0 和3.0的时候才有协变和逆变
//[2]协变和逆变他是针对泛型接口和泛型委托来说的,离开了他们就没有这个说法
//Teacher teacher1 = new People(); //不可以
//[3]out关键字代表是协变,in代表是逆变
//[4]什么情况下使用?在知道自己或者别人以后有用到父类通过子类实例化,或者子类通过父类实例化的情况下可以使用out in关键字
IListOut<People> listOut = new ListOut<People>();
IListOut<People> listOut1 = new ListOut<Teacher>();//协变
IListIn<Teacher> listIn = new ListIn<Teacher>();
IListIn<Teacher> listIn1 = new ListIn<People>();//逆变
IOutInList<Teacher, People> myList1 = new OutInList<Teacher, People>();
IOutInList<Teacher, People> myList2 = new OutInList<Teacher, Teacher>();//协变
IOutInList<Teacher, People> myList3 = new OutInList<People, People>();//逆变
IOutInList<Teacher, People> myList4 = new OutInList<People,Teacher>();//协变+逆变
#endregion
}
}
#region 协变和逆变
class People//父类
{
public int Id { get; set; }
}
class Teacher : People
{
public string Name { get; set; }
}
/// <summary>
/// 协变只能返回结果,不能做参数
/// </summary>
/// <typeparam name="T"></typeparam>
interface IListOut<out T>
{
T GetT();
//void Show(T t);
}
class ListOut<T> : IListOut<T>
{
public T GetT()
{
return default(T);//default关键字,如果是值类型默认返回0,是引用类型默认返回null
}
}
/// <summary>
/// in修饰,逆变后,T只能作为当参数 不能返回值
/// </summary>
/// <typeparam name="T"></typeparam>
interface IListIn<in T>
{
//T GetT();
void Show(T t);
}
class ListIn<T> : IListIn<T>
{
public void Show(T t)
{
}
}
public interface IOutInList<in inT, out outT>
{
void Show(inT t);
outT GetT();
outT Do(inT t);
//out只能是返回值,in只能是参数
//void Show(outT t);
//inT GetT();
}
public class OutInList<T1, T2> : IOutInList<T1, T2>
{
public void Show(T1 t)//逆变作为参数
{
}
public T2 GetT()//协变作为返回值
{
return default;
}
public T2 Do(T1 t)
{
return default(T2);
}
}
#endregion
}
版权声明:本文为weixin_47896156原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。