C#协变逆变

用于 泛型中修饰泛型字母的,只有泛型接口和泛型委托能使用!!!

协变:out

和谐的变化 , 自然的变化,因为里氏替换原则父类可以装子类,所以子类变父类

逆变:in

逆常规的变化 , 不正常的变化,因为里氏替换原则父类可以装子类但是子类不能装父类,所以父类变子类

完整代码:

using System;
namespace Test
{
	//1.返回值和参数
	//2.用out修饰的泛型,只能作为返回值
	delegate T TestOut<out T>();
	//delegate T TestOut<out T>(T t);// 不能作为参数
	//3.用 in 修饰的泛型只能作为参数
	delegate void TestIn<in T>(T t);
	//delegate T TestIn<in T>(T t);// 不能作为返回值
	//4.只有泛型接口和泛型委托能使用
	//class Test<in T>//错误
	//{
	//
	//}
	//5.结合里氏替换原则理解
	class Father
	{}
	class Son:Father
	{}
	class Program
	{
		public static void Main(string[] args)
		{
			//协变
			TestOut<Son> os = ()=>
			{
				return new Son();
			};
			TestOut<Father> of = os;//协变就是父类泛型委托装载子类泛型委托
			//如果delegate T TestOut<out T>();没有out则无法转换,实际返回的是os里的函数返回值为Son
			//逆变
			TestIn<Father> inf = (value)=>
			{
			};
			TestIn<Son> ins =inf;//逆变就是子类泛型委托装载父类泛型委托
			//如果delegate void TestIn<in T>(T t);没有in则无法转换,实际返回的是inf里的函数参数为Father value
			Console.ReadKey();
		}
	}
}

协变(covariant)和逆变(contravariant)是指在继承关系中子类的类型如何与父类的类型进行比较。

协变指的是子类可以转换为更通用的父类,即子类的类型参数是父类类型参数的子类型。例如,一个返回IEnumerable类型的方法可以返回IEnumerable类型,因为string类型是object类型的子类型。在C#中协变用out关键字表示,只能用于接口和委托的类型参数。

逆变指的是子类可以转换为更特定的父类,即子类的类型参数是父类类型参数的父类型。例如,一个接受IComparer类型参数的方法可以接受IComparer类型,因为object类型是string类型的父类型。在C#中逆变用in关键字表示,只能用于委托的类型参数。

// 协变示例
IEnumerable<string> strings = new List<string>();
IEnumerable<object> objects = strings; // 可以进行协变
// 逆变示例
Comparison<object> comparison = (object1, object2) => 0;
Comparison<string> stringComparison = comparison; // 可以进行逆变

需要注意的是,虽然协变和逆变可以方便地处理一些类似转换的问题,但它们也会导致一些安全隐患和类型不匹配的错误,因此需要仔细考虑使用场景和实际需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

睡不着乌托托

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值