写点什么

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

评论

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

C/C++size(),sizeof(),length(),strlen()对比分析详解

CtrlX

c c++ 进阶 热门活动 8月月更

华为云构建“好用的化工数字化”

IT资讯搬运工

重学网络系列之(UDP)

自然

网络 8月月更

leetcode 242. Valid Anagram 有效的字母异位词(简单)

okokabcd

LeetCode 算法与数据结构

【Python编程技巧】简单理解和使用Python中@property

迷彩

@PropertySource 8月月更 Python编程技巧

自此乾坤始:中国量子计算产业化的激变时刻

脑极体

Spring Boot 运行的时候提示日志错误

HoneyMoose

蓝凌“智慧云脑”,助力水务、燃气等集团服务民生

科技怪咖

从工程预算到项目管理,『蓝凌低代码』让房企管理更简单

科技怪咖

Spring 项目启动错误提示 LoggingApplicationListener

HoneyMoose

每日一R「15」实践课之 kv-server(一)

Samson

学习笔记 8月月更 ​Rust

ISO文件怎么管?“筷子第一股”双枪科技教你1招!

科技怪咖

Java集合之map集合

楠羽

#开源

阿里云-建站小能手快速体验

凌云Cloud

阿里云 网站建设

高效率团队为啥都会选择Jenkins?一文带您了解Jenkins

wljslmz

持续集成 jenkins 8月月更

重学网络系列之(TCP)

自然

网络 8月月更

[极致用户体验] 教你个超牛逼的分割线CSS!

HullQin

CSS JavaScript html 前端 8月月更

规范代码命名,让你的代码阅读起来更愉悦!

岛上码农

flutter 前端 移动端开发 跨平台开发 8月月更

重学网络系列之(Ping与网关)

自然

网络 8月月更

如何给注册中心锦上添花?

捉虫大师

微服务 架构设计 注册中心 服务发现 8月月更

Polkadot + DeFi | 透明公平、高效交易的去中心化金融未来可期

One Block Community

区块链 金融创新 defi 波卡生态

Zabbix 监控系统保姆及教程

CTO技术共享

浅谈DingOS 设备端计算

鼎道智联

隐私安全 智能推荐 本地计算 服务推荐

解析大型电商网站系统架构分层设计

穿过生命散发芬芳

网站架构 8月月更

负载均衡算法

源字节1号

程序员 软件开发

「美团 CodeM 资格赛」数码 详解

Five

c++ 算法题 8月月更

【Arthas】初识Arthas,安装使用

石臻臻的杂货铺

Arthas 8月月更

从 Multirepo 到 Monorepo 袋鼠云数栈前端研发效率提升探索之路

袋鼠云数栈

蓝凌生态OA,重新定义中大型企业数字化办公

科技怪咖

聚焦“工业互联网+危化安全生产”,工智道入驻华为云严选商场

IT资讯搬运工

React在实际开发中Variables与Prop的实战运用

恒山其若陋兮

8月月更

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