2025上半年,最新 AI实践都在这!20+ 应用案例,任听一场议题就值回票价 了解详情
写点什么

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:0011831

评论

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

奈学教育荣获“中关村高新技术企业”认证

古月木易

教育 IT

腾讯云直播全解析,双11怎么买才不亏?

腾讯云音视频

腾讯云 阿里云 云直播 直播 视频

年末十家手机银行数字化升级大盘点:谁家开发更全面?谁家建设更到位?

CECBC

疫情 银行 手机银行

腾讯WeMap,一颗“孢子”的数智化之旅

脑极体

【概念篇】你真正了解越来越火的“数据驱动” 吗?

Java架构师迁哥

当Tomcat遇上Netty,我这一系列神操作,同事看了拍手叫绝

小Q

Java 学习 程序员 架构 面试

技术干货:Apache Pulsar 在移动云上的应用

Apache Pulsar

大数据 开源 云原生 Apache Pulsar

第七周作业

Geek_4c1353

极客大学架构师训练营

阿里首发MySQL“完美日记”,基础+优化+事务+集群+锁+主从复制+安全备份

Java架构追梦

Java MySQL 数据库 架构 面试

Java批量导入去除重复数据并返回结果,我差点就被放倒了

小Q

Java 学习 程序员 架构

科技助力餐饮,普渡送餐机器人在餐博会上被众人围观!

DT极客

重拳出击!平台经济反垄断,互联网巨头市值蒸发千亿

CECBC

小额贷款 反垄断

面试蚂蚁金服,首战被MySQL惨虐,熬夜啃透这份阿里面经复盘一个月再战拿下P7offer

比伯

Java 程序员 架构 面试 阿里

【Mycat】Mycat核心开发者带你看尽Mycat三大核心配置文件!!

冰河

分布式数据库 中间件 mycat

当Nginx遇上Tomcat集群,又是一场负载均衡的爱恨情仇

小Q

nginx tomcat 学习 架构 面试

面试官问我redis数据类型,我回答了8种

数据库 学习 面试

SpringBoot启动原理

编程门槛 框架设计 spring Boot Starter】

对比一下,你的简历是不是也写成了这样,能拿高薪才怪了

小Q

Java 学习 架构 面试 简历

浅谈程序员的“内卷化”

数据社

LeetCode题解:剑指 Offer 22. 链表中倒数第k个节点,使用栈,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

要求自愿降薪,员工内心普遍满意:“服从”是如何发生的?

脑极体

践行新基建,共建城市智能体,为数字经济发展提供新动能

CECBC

云计算 大数据

《我想进大厂》之Java基础夺命连环16问

艾小仙

Java 面试 编程语言

架构训练营-week8-数据结构与算法,网络,IO

于成龙

极客大学架构师训练营 架构训练营

双“11”搞促销?本文教你用贪心算法来盘他!

Java架构师迁哥

阿里突遭断网断电!双11最惊险一幕刚刚曝光

Java架构师迁哥

11.11 程序员的 1111 种死法

京东科技开发者

程序员 程序人生

iptables 端口转发

田振宇

搞微服务用阿里开源的 Nacos 真香啊!

阿里巴巴 开源 编程

「架构师训练营」第 4 周作业

小黄鱼

极客大学架构师训练营

MySQL 的 join 功能弱爆了?

程序员历小冰

MySQL postgres 多表join

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