写点什么

C#的未来:协变返回类型

  • 2020-02-04
  • 本文字数:1028 字

    阅读完需:约 3 分钟

C#的未来:协变返回类型

一个常见的 API 设计问题是无法在重写方法时使用更具体的返回类型。Clone 方法就是一个很好的例子。


public abstract Request Clone();
复制代码


在子类中,你可能会希望像下面这样实现这个方法:


public override FtpRequest Clone() { ... }
复制代码


由于 FtpRequest 是 Request 的子类,从逻辑上讲这是合理的。但在.NET 中你不能这样实现,因为重写必须精确匹配。你也不能通过重写获得一个仅有返回类型不同的新方法。所以通常你会得到一些复杂的东西,比如:


public Request Clone() => OnClone();protected abstract Request OnClone();
复制代码


然后,在子类里:


public new FtpRequest Clone() => (FtpRequest)OnClone();protected override Request OnClone() { ... }
复制代码


提案49在“协变返回类型”中探讨了改变被重写方法返回类型的能力。


在 2017 年最初提出时,这个特性应该是使用一些“编译器魔法”实现的。到 2019 年 10 月,重点已经转向使它成为 CLR 的一等特性。


协变返回类型规范草案中,IL 指令.override 将变成:


重写方法的返回类型必须可以通过标识或隐式引用转换为被重写的基方法的返回类型。


当前的规则是:


重写方法和被重写的基方法应具有相同的返回类型。

属性和索引器

属性和索引器包括在此特性中,但仅当它们是只读的。该特性不会对逆变属性和索引设置器提供匹配支持。

接口

接口上的方法可以使用与子类/基类相同的规则重写基接口上的协变方法。


当类实现接口时,实现方法可以与接口方法协变。


为了进行接口映射,类成员 A 在以下情况下与接口成员 B 匹配:

A 和 B 是方法,A 和 B 的名称和形式参数列表相同,A 的返回类型可以通过一个隐式引用标识转换为 B 的返回类型。


对于隐式实现的接口,这种规则变化可能会导致破坏性更改。这种情况会在子类重新实现基类已经实现的接口时发生。


interface I1 { object M(); }class C1 : I1 { public object M() { return "C1.M"; } }class C2 : C1, I1 { public new string M() { return "C2.M"; } }
复制代码


为了避免破坏性更改,Andy Gocke 对规则做了一个小小的修改:


如果没有其他实现(包括默认实现),我们是否可以更改映射成员的搜索,将具有不同协变返回类型的隐式实现考虑进来?


遗憾的是,这与接口的默认实现不兼容。Neal Gafter 写到:


我看不出这在二进制兼容的情况下是如何工作的。如果发布了带有默认实现的新版本的接口,那么运行时将更改为使用该接口,而不是使用基类的实现?


微软内部正在跟踪对协变返回类型提供必要的运行时支持的优先级。


原文链接:


C# Futures: Covariant Return Types


2020-02-04 09:0011396

评论

发布
暂无评论
发现更多内容

阿里巴巴“高并发”天花板教程《基础+实战+源码+面试+架构》

程序知音

Java 高并发 阿里 多线程与高并发 java架构

Wallys /QCA9880 vs QCA9882/802.11ac Solution/MU-MIMO

wallys-wifi6

QCA9880 QCA9882

天翼云全场景业务无缝替换至国产原生操作系统CTyunOS!

天翼云开发者社区

系统

天翼云安全一体化纵深体系是怎么炼成的?

天翼云开发者社区

云安全

银河麒麟、中标麒麟学习实操资料汇总(含V4、V7、V10)

墨天轮

操作系统 国产化 银河麒麟 中标麒麟

测试人生 | 双非院校、入职某知名电商公司薪资翻倍还有股票奖励,这个90后小姐姐也太飒了吧?

霍格沃兹测试开发学社

参加Java培训能学到开发技术吗?

小谷哥

测试人生 | 从跨专业手工测试转岗外包,再到 Python 测试开发,跳槽涨薪 85%!

霍格沃兹测试开发学社

测试人生 | 半年涨薪20W入职名企大厂,这个90后妹纸凭什么这么猛?

霍格沃兹测试开发学社

数据湖管理及优化

阿里云大数据AI技术

大数据 spark 数据湖 企业号九月金秋榜

测试人生 | 从小团队的业务到独角兽的测开,涨薪超过60%,90后小哥哥凤凰涅槃了

霍格沃兹测试开发学社

易观千帆 | 2022年7月银行APP活跃用户规模盘点:江浙沪城商行表现亮眼

易观分析

App 金融 银行

Java培训学生可以学到哪些开发技术呢

小谷哥

100+大屏模板免费领!葡萄城BI行业应用方案重磅发布!

葡萄城技术团队

BI 发布会

是什么引起数据库响应超时?

BUG侦探

MySQL AWS 云服务

如何选择靠谱的西安培训机构?

小谷哥

企业上云安全感多“亿”点!

天翼云开发者社区

QA如何高效参与技术设计评审

转转技术团队

质量管理 测试 技术设计质量把控

开发者个人成长主题征文挑战赛正式启动!说出你的成长故事共谱青春乐章

InfoQ写作社区官方

个人成长 热门活动

年轻一代程序员:社牛、不卷、玩开源

腾源会

开源 腾源会

自学Java和java培训哪个好就业

小谷哥

JAVA开发培训哪家比较好

小谷哥

会当“零”绝顶!天翼云零信任产品利刃出鞘

天翼云开发者社区

安全

测试人生 | 从外行到外包,从手工测试到知名互联大厂测开 这个90后小姐姐是怎么腾飞的?

霍格沃兹测试开发学社

测试人生 | 做了低薪运营6年,妹纸靠什么转行拿下 20W 年薪?

霍格沃兹测试开发学社

人工智能、机器学习与深度学习的区别在哪里?

Finovy Cloud

人工智能 深度学习

Java进阶(二十八)SimpleDateFormat格式化日期问题

No Silver Bullet

Java 9月月更

CentOS时代即将结束 国产系统能否避免“受限”覆辙?

天翼云开发者社区

计算机网络——数据链路层

StackOverflow

编程 计算机网络 9月月更

Databend JSON 复杂数据类型的设计与使用 | Databend 特性系列

Databend

json

测试人生 | 双非学历入职名企大厂还薪资翻倍?

霍格沃兹测试开发学社

C#的未来:协变返回类型_编程语言_Jonathan Allen_InfoQ精选文章