写点什么

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

2020 年 2 月 04 日

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 年 2 月 04 日 09:002054

评论

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

怎么才能写出100个用户体验的关键时刻?

石云升

读书笔记 用户体验 关键时刻 7月日更

上线仅7天,GitHub已标星48.4k!原来是阿里巴巴内部《高并发系统设计》

云流

Java redis 编程 架构 面试

线上教育培训机构如何推广自己

石头IT视角

可以同时管理公有云和私有云资源的软件哪个好?

行云管家

公有云 私有云 云管平台 云资源

6月热点:BML全新升级WebIDE编程环境,度目智能视频分析盒G1上新

百度大脑

人工智能 BML

百度AI寻人获评《新周刊》2021年度公益项目

百度大脑

人工智能 寻人

程序员必备的思维能力:结构化思维

互联网架构师小马

【等保知识】等保测评机构申请条件,所需资料以及流程

行云管家

等保 堡垒机 行云管家 等保测评

启动、内存、卡顿三大分析,用户体验就用它?

友盟全域数据

App

《人这一辈子,都在为认知闭环买单》读后感---刘润

Changing Lin

【得物技术】得物开放平台进阶之路

得物技术

安全 后端 平台 订单

Ipfs国家认可吗?国家对ipfs区块链是什么政策?

IPFS星盟小熊

区块链 分布式存储 IPFS fil

结构化流-Structured Streaming(八-下)

数据与智能

spark 流式计算框架 structuredStreaming

极光开发者周刊【No.0723】

极光开发者

阿里数据中台底座的12年建设实践

阿里云大数据AI技术

从零开始学习3D可视化之数据对接(3)

森友小锘

前端 数据 物联网 可视化 数字孪生

实战-使用 SSM 工具创建可动态扩容的存储池

学神来啦

Linux 运维 ssm Linux教程

药物研发使用北鲲云高性能计算平台,有效解决研发效率问题

北鲲云

实践解析丨如何通过 WebAssembly 在 Web 进行实时视频人像分割

声网Agora

前端 WebRTC webassembly

我学编程时最后悔的事!

程序员鱼皮

Java c++ Python 前端 后端

使用数据库乐观锁的方式解决数值累加的问题

陈靓-哲露

【入门必读】《TcaplusDB数据库常见问题解决及诊断技巧集锦-数据库使用类-1》

TcaplusDB

nosql Data TcaplusDB tencendb

金钟罩还是铁布衫?TcaplusDB定时备份助你万无一失!

TcaplusDB

数据库 nosql Data TcaplusDB

我不想干外包了,连续两次跳槽,我有幸成为了字节跳动的一名Java后端开发~

Geek_33f0ef

Java 编程 程序员 面试 架构师

Android Flutter 多实例实践

网易云信

flutter 架构

学习下服务器端漏洞,受益匪浅!

网络安全学海

运维 网络安全 信息安全 漏洞扫描 渗透测试·

金钟罩还是铁布衫?TcaplusDB定时备份助你万无一失

tcaplus

TcaplusDB

升级数据库游戏不停服?来看看TcaplusDB是怎么操作的(3)

TcaplusDB

nosql Data TcaplusDB tencendb

程序员必备的思维能力:抽象思维

互联网架构师小马

模块三作业

燕燕 yen yen

架构训练营

inft.io首创鉴价机制,弥补NFT生态空缺

区块链小八歌

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