【ArchSummit架构师峰会】探讨数据与人工智能相互驱动的关系>>> 了解详情
写点什么

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

评论

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

租便宜的云服务器能干啥?有什么好处?怎么选择?

行云管家

云计算 服务器 云服务器

偶数层PCB板为何在PCB多层板中“独领风骚”?

华秋PCB

工艺 PCB PCB设计

瓴羊Quick BI企业数据分析工具,公司运营实时掌控

巷子

海量数据 x 宝兰德 x openGauss Meetup成功举办,广州用户组正式成立!

openGauss

元年智答|数据洞察功能介绍

元年技术洞察

人工智能 数字化转型 智能

欢迎航天宏图加入社区

openGauss

事务

ssun

事务 JAV A 11月月更

Wallys/IPQ8072/IPQ8074/2x(4×4 or 8×8) 11AX/IPQ6010 (IPQ6018 FAMILY)/industrial wifi6 moudle

wallysSK

IPQ6010 ipq6018 IPQ8072 IPQ8074

面试官:介绍一下 Redis 三种集群模式

Jeremy Lai

redis集群

大咖说·图书分享|深入浅出Node.js

大咖说

node.js

《Python编程:从入门到实践》有奖书评活动来啦!

图灵社区

从多个角度分析顺序表和链表区别和特点

C++后台开发

数据结构 算法 链表 linux开发 C++开发

RocketMQ 客户端负载均衡机制详解及最佳实践

阿里巴巴云原生

阿里云 RocketMQ 云原生

WebGL入门之基于WebGL的Sovit3D可视化平台

2D3D前端可视化开发

数据可视化 WebGL 三维可视化 web3d 3d绘图引擎

C语言学生管理系统

我是一个茶壶

C语言 学生成绩管理系统 11月月更

多云时代,如何构建配置管理数据库?

BoCloud博云

(Java开发岗)了解大厂面试基本套路及每一轮的重点

程序知音

Java 后端 java面试 java架构 互联网大厂面试

openGauss内核荣获中国首个国际CC EAL4+级别认证

openGauss

openGauss —— 智能优化器之基数估计

openGauss

使用 Rainbond 搭建本地开发环境

北京好雨科技有限公司

Kubernetes rainbond

面霸是怎样练成的?“2023”带你过关斩将,手撕面试官

钟奕礼

Java 程序员 java面试 java编程

2022年中国新能源汽车出海市场发展洞察

易观分析

新能源汽车 出海

2023跳槽一定不能错过的java面试集——前百度资深架构师整理

钟奕礼

Java 程序员 java面试 java编程

openGauss 3.1.0的新型选择率模型大解密

openGauss

openGauss的SQL引擎在3.1.0版本中做了哪些优化?

openGauss

如何拆掉跨部门的墙?

PMO实践

项目管理 企业管理 跨部门沟通

精彩回顾 | 苏州农商银行新一代云原生信息科技架构体系实践

BoCloud博云

云原生

多场景下 3-11 倍性能提升,Apache Doris 1.2 新版本性能揭秘!

SelectDB

数据库 数据分析 Clickhouse Doris 数仓

为啥PMO困惑的起因和其他职能部门不一样?

PMO实践

项目管理 PMO

极客时间架构训练营模块八作业

李晨

架构

金奖方案 | 一专多能、傲视寰宇,南大通用GBase8c数据库牛在哪里?

openGauss

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