Qwen3 惊喜上线阿里云百炼,8款模型全开源!点击免费领取 800万 tokens! 了解详情
写点什么

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

评论

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

话说cas

木子的昼夜

Apache Ranger的部署安装

大数据技术指南

大数据 3月日更

LeetCode题解:518. 零钱兑换 II,动态规划,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

冰河公开了进大厂的核心技能,服了!

冰河

程序员 面试 大厂技能 硬核技能图谱

SRS流媒体服务器源码分析--RTMP消息play

赖猫

音视频 流媒体 SRS 流媒体开发

芯翌科技领跑NIST-FRVT戴口罩人脸识别评测,助力后疫情时代科技创新

朋湖网

搞定计算机网络的常见面试问题

线上MySQL读写分离,出现写完读不到问题如何解决

程序员历小冰

MySQL 读写分离

Wireshark数据包分析学习笔记Day5

穿过生命散发芬芳

Wireshark 数据包分析 3月日更

十四五,鹏城应作先锋看,山河同襄智能体

脑极体

接口测试--apipost接口断言详解

测试人生路

接口

2021金三银四必备:“基础-中级-高级”Java程序员面试复习路线

比伯

Java 编程 程序员 架构 面试

什么是职业

ES_her0

28天写作 3月日更

更新60篇的复盘:持续书写,见证文字的力量

boshi

写作 七日更

几千次的重复提交,我用 SpringBoot+Redis 居然扛住了!

Java小咖秀

redis 后端 springboot 幂等

Linux/Centos Epoll 原理解析

赖猫

Linux 高并发 epoll

新人报道

shun123456789

女神营业!云通信产品运营带你玩转号码隐私保护:网约车、外卖等O2O行业的最佳实践

阿里云Edge Plus

云通信 通信云

翻译:《实用的Python编程》04_02_Inheritance

codists

Python 继承 inheritance

容器 & 服务:K8s 与 Docker 应用集群 (四)

程序员架构进阶

Docker Kubernetes 容器 28天写作 3月日更

one day

旭陽

redis工作原理(上)

Sakura

28天写作 3月日更 21天挑战

雪花算法,到底是个啥?

架构精进之路

算法 七日更 3月日更

音视频之opengl渲染图片

赖猫

音视频

半个多月时间4面阿里,已经成功拿下offer,分享一下个人面经

Java架构之路

Java 程序员 架构 面试 编程语言

Go语言学习笔记:抓取XKCD中文站的漫画

worry

Go 语言

程序员成长第二十三篇:员工不符合预期,怎么办?

石云升

程序员 28天写作 职场经验 管理经验 3月日更

准备参加软考的小伙伴注意了!

IT蜗壳-Tango

IT蜗壳 3月日更

深入理解Linux内核 RCU 机制

赖猫

Linux linux编程 Linux内核

职场求生攻略答疑篇之 5 —— 我,程序员,非常焦虑

臧萌

职场 成长

拼多多五面面经(Java岗),全面涵盖Java基础到高并发级别

Java架构之路

Java 程序员 架构 面试 编程语言

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