NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

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

评论

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

大数据训练营-0711课后作业

cc

勇于尝试新鲜事物,利于项目来积累学习经验

DisonTangor

职业规划

从脑瘫患者重获交流到免开颅微创,脑机接口更安全了吗?

脑极体

软件库与框架的区别

码语者

架构 框架

【涨知识】你不知道的Python常用开发工具!猿来这么多!

小阿杰

Python 后端 开发工具

Nginx配置location

刘旭东

nginx 反向代理

Linux之du命令

入门小站

Linux

统一语言 = 领域模型 ?

escray

学习 极客时间 7月日更 如何落地业务建模

5分钟速读之Rust权威指南(四十三)宏

wzx

rust

在腾讯,我的试用期总结

程序员鱼皮

Java c++ Python 大前端 后端

小解c# foreach原理

喵叔

7月日更

nacos的作为服务配置怎么玩?

卢卡多多

nacos 服务 7月日更

JIRA 如何连接到云平台的 bitbucket

HoneyMoose

架构训练营模块二作业

Lemon

想跳槽却简历石沉大海?一起来围观月薪20k的软件测试工程师真实简历 (含金量高面试题)

程序员阿沐

面试 软件测试 自动化测试 经验分享 简历

图像的读取,显示与存储操作

IT蜗壳-Tango

7月日更

想在Java八股文面试中脱颖而出?这《1000道互联网大厂Java工程师面试题》必不可少!

Java 编程 程序员

想在Java八股文面试中脱颖而出?这《1000道互联网大厂Java工程师面试题》必不可少!

白亦杨

Java 编程 程序员

【Kubernetes技术专题】系统架构介绍

洛神灬殇

k8s 7月日更

在线XML转HTML工具

入门小站

工具

免费分享Mysql从入门到精通的优秀图书

Java入门到架构

Druid 0.15 版本启动错误

HoneyMoose

区块链技术如何赋能食品安全链路追溯

CECBC

【设计模式】工厂模式

Andy阿辉

编程 程序员 设计模式 23种设计模式

CTF中的一些常见骚操作(可以没有,但不能不会)

网络安全学海

网络安全 信息安全 CTF 渗透测试 漏洞分析

数字人民币的基础:共识与信任

CECBC

[架构实战营]模块二作业

xyu

#架构实战营

JIRA 链接 bitbucket 提示错误 Invalid OAuth credentials

HoneyMoose

优化和调整Spark应用程序(七)

数据与智能

spark 缓存 持久化

数字化转型下的数字经济新发展

CECBC

【设计模式】总览

Andy阿辉

编程 程序员 设计模式 23种设计模式

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