泛型参数转换的问题

泛型不同参数类型生成的对象是相互独立的。

//
Tuple<string> ts;
Tuple<object> to;
//ts to 是两个类型的对象。

很多时候,我们希望实现 to = ts 这种操作,为什么?因为看上去它应该如此。

为了达到这个目的,就要解决“泛型参数转换的问题”,这个问题的知识点是in out 泛型变体。老实说,这个问题本身不困难,只是非常不直观,很容易让人忘记。

首先一点,为了实现to = ts,实际上是有前提的,那就是该参数只能用在“返回类型”上。

//
delegate object FuncObj();FuncObj func = ()=>"string";

func之所以成功,就是因为string 可以转换成 object。当“用户”调用func,希望得到的是object对象,而string也是object对象,所以没有任何问题。

这里的关键是学会采用"用户"的视角分析问题。

//A
delegate void FuncObj2(object obj);
FuncObj2 func2 = (string str)=>{};
//B
delegate void FuncStr(string str);
FuncStr func3 = (object obj)=>{};


分析这两组代码,哪一个更加合理?

在用户角度,它使用的是func2 和 func3

用户使用func2,传递的对象必然是object,但实际处理的函数是(string)=>{},object是无法转换成string的,所以很不合理。

用户使用func3,传递的对象只能是string,而实际处理的函数是(object)=>{},string 是可以转换成object的,所以是合理的。

当然这两组代码都是不成立的,因为函数参数类型不匹配。

但是泛型提供了一个方法,让类型不匹配的对象之间能够隐式转换!它实现的逻辑就是上面分析的。

//out 修饰返回类型
delegate ResultType FuncOut<out ResultType>();
//in 修饰参数类型
delegate void FuncIn<in ParamType>(ParamType param);//这是一开始我们想做到的目标
FuncOut<object> fun4 = () => "string";
//这个效果恰好相反
FuncIn<object> funcobj = (object obj) => { };
FuncIn<string> fun5 = funcobj;//注意,泛型变体一般只能和泛型变体之间隐式转换
//lambda表达式会自动转换成参数相同的泛型变体,但无法接着做变体之间的隐式转换,所以需要funcobj来过渡

out修饰返回类型,in修饰参数类型,还是挺形象的,但是要注意泛型in参数,和out参数正好相反。

开始我们想实现 to = ts,只是看到问题的一半,实际上泛型是存在 ts = to的可能性的,希望读者能理解这一点。

总结:

out : to = ts;

in : ts = to;

没有修饰:to,ts完全独立。

---------------------------(备注)-------------------------------
out 参数:只能用在返回类型。

in 参数:只能用在参数。

没有修饰:任意位置。

---------------------------(备注2)------------------------------

in、out泛型参数只能用在委托和接口上面。

//综合运用
delegate ResultType FuncInOut<in ParamType, out ResultType>(ParamType param);FuncInOut<object, string> funcobj2 = (object obj) => "string";FuncInOut<string, object> func6 = funcobj2;

转载于:https://www.cnblogs.com/Nobel/p/6361312.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/255508.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【python数字信号处理】——循环卷积(也叫圆圈卷积)

目录 一、公式 二、代码 方法一:遍历 方法二:利用卷积定理 一、公式

UI-UIScrollView

- (void)viewDidLoad { [super viewDidLoad]; scrollView [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)]; scrollView.backgroundColor [UIColor redColor]; // 是否支持滑动最顶端 // scrollView.scrollsToTop NO; scrollView.delegate self; // 设…

[COCI2015]ZGODAN

题目大意&#xff1a;   给你一个数$n(n\leq10^1000)$&#xff0c;定义一个数是“美丽数”当且仅当这个数各个数位上的数奇偶性不同。   求最接近$n$的“美丽数”&#xff0c;若有多个&#xff0c;则依次输出。 思路&#xff1a;   贪心高精度。   首先找出$n$的第一个…

OpenCV学习笔记(三)——Mat,图像的新容器

自从版本2.0&#xff0c;OpenCV采用了新的数据结构&#xff0c;用Mat类结构取代了之前用extended C写的cvMat和lplImage&#xff0c;更加好用啦&#xff0c;最大的好处就是更加方便的进行内存管理&#xff0c;对写更大的程序是很好的消息。 需要注意的几点&#xff1a;1. Mat的…

jq实现事件委托

事件委托首 页产品展示公司简介关于我们联系我们转载于:https://www.cnblogs.com/haley168/p/eventTarget.html

【python数字信号处理】——scipy库设计滤波器(IIR为例)、绘制滤波器频谱响应、IIR滤波器滤波、读写wav音频文件

目录 一、参考文献 1、scipy接口 2、scipy库介绍+IIR滤波器设计(含GUI)+绘制频谱响应

关于SQL查询效率,100w数据,查询只要1秒

原文:关于SQL查询效率&#xff0c;100w数据&#xff0c;查询只要1秒1.关于SQL查询效率&#xff0c;100w数据&#xff0c;查询只要1秒&#xff0c;与您分享:机器情况p4: 2.4内存: 1 Gos: windows 2003数据库: ms sql server 2000目的: 查询性能测试,比较两种查询的性能SQL查询效…

OpenCV学习笔记(五十四)——概述FaceRecognizer人脸识别类contrib

在最新版的2.4.2中&#xff0c;文档的更新也是一大亮点&#xff0c;refrence manual扩充了200多页的内容&#xff0c;添加了contrib部分的文档。contrib就是指OpenCV中新添加的模块&#xff0c;但又不是很稳定&#xff0c;可以认为是一个雏形的部分。这次结合refman的阅读&…

【调试】Linux下超强内存检测工具Valgrind

【调试】Linux下超强内存检测工具Valgrind 内容简介 Valgrind是什么&#xff1f;Valgrind的使用Valgrind详细教程1. Valgrind是什么&#xff1f; Valgrind是一套Linux下&#xff0c;开放源代码&#xff08;GPLV2&#xff09;的仿真调试工具的集合。Valgrind由内核&#xff08;c…

【python学习】——读取csv文件

file_name rD:\ParttimeJobs\MinistConfiguration\datas\mnist_train.csv # 数据集为42000张带标签的28x28手写数字图像y []x []y_t []x_t []with open(file_name, r) as f:reader csv.reader(f)header_row next(reader)# print(header_row)for row in reader:if np.ra…

机器学习实战(python)-Ch02KNN-Notes

Chapter2 KNN 1.numpy.tile函数 格式&#xff1a;tile&#xff08;A,reps&#xff09; * A&#xff1a;array_like * 输入的array * reps&#xff1a;array_like * A沿各个维度重复的次数 举例&#xff1a;A[1,2] 1. tile(A,2) 结果&#xff1a;[1,2,1,2] 2. tile(A,(2,3)) 结果…

猜1-10的数字python脚本

#!/usr/bin/python#coding:utf-8import randomnumrandom.randint(1,10)while True:caiint(raw_input(请输入随机数字:))if cai num:print 猜对了exit()elif cai > num:print 猜大了else:print 猜小了非交互式的cp脚本#!/usr/bin/python#coding:utf-8import sysfile1sys.arg…

惯量匹配和最佳传动比

惯量是刚体绕轴转动惯性的度量&#xff0c;转动惯量是表征刚体转动惯性大小的物理量。它是伺服选型的重要标准&#xff0c;如果惯量匹配不好&#xff0c;会导致电机运行不稳定。如小惯量电机制动性能好&#xff0c;运行反应速度快&#xff0c;适用于轻负载、高速定位的环境;而中…

【pyqt5学习】——滑动条的使用slider

1、获取滑动条当前值: 滑动条名称.value() self.threshold1 self.horizontalSlider.value() self.threahold2 self.horizontalSlider_2.value() 2、滑动条值改变信号绑定槽函数 滑动条名称.valueChanged.connect(槽函数&#xff09; # 滑条值变化 self.horizontalSlider.valu…

hibernate多对一单向外键

hibernate多对一单向外键&#xff1a; 描述&#xff1a; 转载于:https://www.cnblogs.com/blogofwyl/p/5402197.html

Spring在bean配置文件中定义电子邮件模板

在上一篇Spring电子邮件教程&#xff0c;硬编码的所有电子邮件属性和消息的方法体中的内容&#xff0c;这是不实际的&#xff0c;应予以避免。应该考虑在Spring bean 配置文件中定义电子邮件模板。1.Spring的邮件发件人Java类使用 Spring的MailSender接口发送电子邮件&#xff…

斐波那契数列规律的计算。

斐波那契数列就是某一个数&#xff0c;总是前两个数之和&#xff0c;比如0&#xff0c;1&#xff0c;1&#xff0c;2&#xff0c;3&#xff0c;5&#xff0c;8。由于输出是一串数字&#xff0c;可以用列表的结构存储。开始时&#xff0c;列表中有两个值&#xff0c;即0&#xf…

【PyQt5学习】——颜色面板使用(QcolorDialog)

from PyQt5.QtGui import * from PyQt5.QtCore import * from PyQt5.QtWidgets import * BB = QDialogButtonBox# 颜色窗口 class ColorDialog(QColorDialog):def __init__(self, parent=None):super(ColorDialog, self).__init__(parent)self.setOption(QColorDialog.ShowAlph…

PropertyPlaceholderConfigurer实现配置文件读取

PropertyPlaceholderConfigurer实现配置文件读取 PropertyPlaceholderConfigurer类的主要的用法是将BeanFactory里定义的内容放在一个.properties的文件中. PropertyPlaceholderConfigurer是个bean工厂后置处理器的实现&#xff0c;也就是BeanFactoryPostProcessor接口的一个实…

算法练习5---快速排序Java版

基本思想&#xff1a;通过一趟排序将要排序的数据分割成独立的两部分&#xff0c;其中一部分的所有数据都比另外一部分的所有数据都要小&#xff0c;然后再按此方法对这两部分数据分别进行快速排序&#xff0c;整个排序过程可以递归进行&#xff0c;以此达到整个数据变成有序序…