[C#]in/out关键字与协变逆变
2022/2/26 17:51:43
本文主要是介绍[C#]in/out关键字与协变逆变,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
C#提供了一组关键字in&out
,在泛型接口和泛型委托中,若不使用关键字修饰类型参数T
,则该类型参数是不可变的(即不允许协变/逆变转换),若使用in
修饰类型参数T
,保证“只将T
用于输入”,则允许T
的逆变转换;若使用out
修饰类型参数T
,保证“只将T
用于输出”,则允许T
的协变转换。下面我们解释两个问题:
- 为什么类型参数
T
仅用于输出时可以进行协变转换? - 为什么类型参数
T
仅用于输入时可以进行逆变转换?
//定义两个类型 class Animal {} class Dog : Animal {} //定义两个泛型委托 delegate T OutputOnly<T>(); //只将类型参数T用于输出 delegate void ForInput<T>(T obj); //将类型参数T用于输入 //此时协变的含义是:允许将xxx<Dog>类型的委托转换为xxx<Animal>类型的委托 //对于OutputOnly<T>委托: OutputOnly<Dog> ood = ReturnADog; //一个假设的符合该委托约束条件的方法,返回一个Dog对象 //对委托类型进行协变转换: OutputOnly<Animal> ooa = ood; Animal an = ooa.Invoke(); //调用ooa委托时,它期望获取一个Animal对象,而ooa委托实际保存的ReturnADog方法会返回一个Dog对象, //对于ooa委托来说,它成功获取到了一个Animal对象,所以在仅输出时协变转换是合法的 //对于ForInput<T>委托: ForInput<Dog> fid = NeedADog; //一个假设的符合该委托约束条件的方法,要求传入一个Dog对象 //对委托类型进行协变转换: ForInput<Animal> fia = fid; fia.Invoke(new Animal()); //调用fia委托时,fia根据要求传入一个Animal对象,而此时fia委托实际保存的方法需要一个Dog对象 //所以传入的Animal对象不符合要求。fia委托其实是懵逼的,因为在它看来你要的就是Animal啊, //它并不知道实际需要的是Dog对象,所以当将参数T用于输入时,协变转换是非法的 //此时逆变的含义是:允许将xxx<Animal>类型的委托转换为xxx<Dog>类型的委托 //对于ForInput<T>委托: ForInput<Animal> fia = NeedAAnimal; //一个假设的符合该委托约束条件的方法,要求传入一个Animal //对委托类型进行逆变转换 ForInput<Dog> fid = fia; fid.Invoke(new Dog()); //调用fid委托时,fid根据要求传入一个Dog对象,而此时fid委托实际保存的方法需要一个Animal对象 //所以fid委托传入的对象符合要求,所以在用于输入时逆变转换是合法的 //对于OutputOnly<T>委托: OutputOnly<Animal> ooa = ReturnAAnimal; //一个假设的符合该委托约束条件的方法,返回一个Animal //对委托类型进行逆变转换 OutputOnly<Dog> ood = ooa; Dog dog = ood.Invoke(); //调用ood委托时,它期望获取一个Dog对象,而ood委托实际保存的ReturnAAnimal方法会返回一个Animal //所以ood委托等于是被骗了,它想要的根本不是Animal对象,所以在用于输出时逆变转换是非法的
由此可见,仅用于输出时协变转换才合法,仅用于输入时逆变转换才合法,而in&out
关键字正是C#语言设计的用来监督用户“你想用协变/逆变可以,但不许瞎搞类型转换”的关键字,可以说是很优秀的一个特性了。
这篇关于[C#]in/out关键字与协变逆变的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-03-01沐雪多租宝商城源码从.NetCore3.1升级到.Net6的步骤
- 2024-12-06使用Microsoft.Extensions.AI在.NET中生成嵌入向量
- 2024-11-18微软研究:RAG系统的四个层次提升理解与回答能力
- 2024-11-15C#中怎么从PEM格式的证书中提取公钥?-icode9专业技术文章分享
- 2024-11-14云架构设计——如何用diagrams.net绘制专业的AWS架构图?
- 2024-05-08首个适配Visual Studio平台的国产智能编程助手CodeGeeX正式上线!C#程序员必备效率神器!
- 2024-03-30C#设计模式之十六迭代器模式(Iterator Pattern)【行为型】
- 2024-03-29c# datetime tryparse
- 2024-02-21list find index c#
- 2024-01-24convert toint32 c#