开工福利|免费学 2200+ 精品线上课,企业成员人人可得! 了解详情
写点什么

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

评论

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

架构实战营-hw1

WWH

架构实战营

网络安全:SSRF+XXE漏洞挖掘笔记

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 安全漏洞

dddd

askuy

Lombok与Guava

风翱

lombok 10月月更

官方线索|编程技术宇宙——1024挑战活动

Regan Yue

1024我在现场

和12岁小同志搞创客开发:如何驱动LCD1602液晶显示屏?

不脱发的程序猿

少儿编程 智能硬件 创客开发 LCD1602液晶显示屏

模块一作业:微信业务架构图与学生管理系统毕设架构设计

dean

架构实战营

云栖发布|阿里云消息队列 RocketMQ 5.0:消息、事件、流融合处理平台

阿里巴巴中间件

阿里云 RocketMQ 云原生 中间件 云栖大会

LogUtil日志工具类的封装

Changing Lin

10月月更

中文字节长度引起的数据丢失

看山

Netty 10月月更

官方线索|1024和腾讯课堂一起摇霸符

搬砖人

1024我在现场

聊聊开发日常的效率提升工具(全)

从零开始,基于焱融 SaaS 数据服务平台搭建私有 WordPress blog

焱融科技

云计算 技术 分布式 高性能 文件存储

管理者如何授权

石云升

职场经验 10月月更

HMS的三年一诺,开放出璀璨星河

脑极体

Vue进阶(幺肆捌):Vuex 辅助函数详解

No Silver Bullet

Vue 辅助函数 10月月更

如何呈现一款软件产品的介绍页面

boshi

创业 学习笔记

微信对外部搜索引擎开放:自媒体平台开放搜索引擎有哪些意义

石头IT视角

025云原生之Prometheus介绍

穿过生命散发芬芳

云原生 10月月更

聊一聊利用Dijkstra求有向图的最短路径

Regan Yue

算法 10月月更

机器人主板需求配置参数有哪些呢?

双赞工控

微信朋友圈的高性能复杂度分析

Beyond Ryan

架构实战营

nil,看这篇就够了

Rayjun

Go 语言 nil

Docker Desktop 如何运行第一个 Docker 项目

HoneyMoose

作业六:电商微服务系统设计

紫云

ES索引mpping字段数据类型更改过程

李印

elasticsearch 经验分享

实作中的 std::is_detected 和 Detection Idioms (C++17)

hedzr

算法 c++17 Detection Idioms

北鲲云超算平台能够为CAE行业发展提供哪些支持?

北鲲云

HarmonyOS 3.0.0开发者预览版全新发布

科技汇

硝烟弥漫的安全战场,只等一位超级英雄登场

脑极体

Python 编码规范

不负青春不负己🤘

Python Pythonic 编码规范

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