写点什么

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

评论

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

ONE 2.0应用场景解读 | 如何通过时序拓扑直观还原故障传导链路?

博睿数据

可观测性 应用场景 智能运维 博睿数据 ONE平台

华为云区块链三大核心技术国际标准立项通过

科技怪授

开源让这位00后逆袭成为各类大奖收割者

OpenI启智社区

开源 OpenI启智社区 免费算力

聊聊Mybatis的数据源之获取连接

急需上岸的小谢

11月月更

云数据库时代,DBA将走向何方?-v4

科技之光

感恩每一位 RockStar!

StarRocks

数据库

数据监控预警系统,实现不同端信息推送

葡萄城技术团队

前端 数据可视化

广告业务存储神器:华为云GaussDB(for Redis)

秃头也爱科技

三分建设,七分运营|用现代化安全运营应对数据安全风险

爱科技的水月

聊聊Mybatis的类型转换接口TypeHandler

急需上岸的小谢

11月月更

聊聊Mybatis的类型转换注册类TypeHandlerRegistry

急需上岸的小谢

11月月更

关于平台工程的开发者工具链,你还想加点啥?

阿里巴巴云原生

阿里云 微服务 云原生 EDAS

专利解析|多维建模结合AI识别商品特征的方法

元年技术洞察

AI 数字化转型

帮助中心:培养客户自助服务意识的实用工具

Baklib

《数据》杂志 | 浅析《网络安全法》修改对数据合规与隐私计算的影响

洞见科技

阿里 CTO 程立:Severless 化正加速重塑阿里应用架构和研发模式

阿里巴巴云原生

阿里云 Serverless 云原生

kitti数据集在3D目标检测中的入门(二)可视化详解

Studying_swz

人工智能 11月月更

软件架构的定义与分类

穿过生命散发芬芳

架构 11月月更

游戏品类加速回暖,文娱内容持续火热——2022年IAA行业品类发展洞察系列报告·第三期

易观分析

游戏 报告 文娱

如何使用Git进行代码托管

我是一个茶壶

git 代码托管 11月月更

低代码开发是未来软件开发的主流模式

元年技术洞察

低代码 方舟PaaS

从手动测试到自动测试,企业该如何选择?

飞算JavaAI开发助手

成为数字游民,他们为何「All in Web3」?

One Block Community

程序员 web3 数字游民

如何用JavaScripte和HTML 实现一整套的考试答题卡和成绩表

葡萄城技术团队

容器服务 ACK 结合 MSE Ingress,让集群入口流量管理更丰富、更容易

阿里巴巴云原生

阿里云 云原生 容器服务

第三章 TCP/IP ip地址概念与应用

我叫于豆豆吖.

11月月更

一文了解 Go 的复合数据类型(数组、切片 Slice、Map)

陈明勇

Go golang go基础 11月月更

折叠屏“世界杯”开哨,荣耀Magic Vs踢出关键一球

脑极体

Linux 文件基本属性

芯动大师

chmod 11月月更 Linux文件属主 charp chown

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