写点什么

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

评论

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

数字货币钱包开发费用,区块链钱包开发优势

13530558032

SQL数据库:CASE表达式

正向成长

CASE表达式

程序员求助:腾讯面试题,64匹马8个跑道,多少轮选出最快的四匹

Java架构师迁哥

揭秘双11:前端技术体系

大前端

架构师第一期作业(第 9 周)

Cheer

作业

#不吐不快# IT职场里的奇葩经历

InfoQ写作社区官方

职场搞笑 奇葩的经历 热门活动

程序员双十一剁手指南

数据君

腾讯云 程序员

即将写入MySQL源码的官方bug解决之路

数据君

MySQL

有点意思的gif动图生成平台开发实战(二)

徐小夕

Java Vue 大前端 GIF React

【乘风破浪的开发者】丁一超:从AI实战营出发探索未知的AI世界

华为云开发者联盟

华为 AI modelarts

亿级大表分库分表实战总结(万字干货,实战复盘)

学习 编程 架构 计算机网络

覆盖全网的阿里微服务架构有多牛:K8S+实战+笔记+项目教程

Java~~~

Java 程序员 微服务 Spring Cloud 阿里云 K8S

“3+3”看华为云FusionInsight如何引领“数据新基建”持续发展

华为云开发者联盟

数据库 新基建 华为云

这套JVM核心知识你要全都会,月薪还不过18K可以直接跳槽了

小Q

Java 学习 架构 面试 JVM

牛批!2w字的Java集合框架面试题精华集(2020最新版),赶紧收藏。

Java架构之路

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

那个小白还没搞懂内存溢出,只能用案例说给他听了

田维常

内存溢出

不要拿区块链做挡箭牌

CECBC

区块链

断供,危机or契机?开源商业化or社区化?后疫情下的开源路这样走 | 大咖对话

易观大数据

数字货币交易所功能,场外OTC交易所开发公司

13530558032

云算力挖矿模式系统开发,云算力平台搭建

13530558032

数字货币助力支付体系高效运行

CECBC

金融

adb的常用操作命令

Yolanda_trying

花四个月和阿里面试官“大战”7回合,成功将其“斩于马下”!复盘面试题及答案!

Java架构追梦

Java 阿里巴巴 面试 java架构

超越竞争文化:致善式创新能否打造手机产业的“海法城”

脑极体

USDT币支付系统开发搭建,区块链承兑商支付平台

13530558032

「Spring Boot 2.4 新特性」一键构建Docker镜像

AI乔治

Java Docker 架构

Alibaba首发的《Java技术成长笔记》,渴望提升自己的程序员的必备宝典!

Java架构之路

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

《精通lambda表达式:Java多核编程》.pdf

田维常

Lambda

干货!直观地解释和可视化每个复杂的DataFrame操作

计算机与AI

Python pandas 数据处理

报告显示国际区块链监管呈三大趋势

CECBC

区块链 货币 监管

两句话给面试官讲清楚IOC

执墨

spring ioc 依赖倒置原则 springioc 控制反转

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