速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

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

评论

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

如何成为一名合格的CRUD工程师?

博文视点Broadview

Vue进阶(幺柒零):应用 rem/em 实现字体自适应

No Silver Bullet

Vue 自适应 11月日更

一文了解如何使用移动应用安全组件Soot和Flowdroid

华为云开发者联盟

移动应用 安全 Soot Flowdroid APK

写入、读取均优于InfluxDB,TDengine在智慧水务系统中的应用

TDengine

数据库 tdengine 后端

腾讯云发布容器安全白皮书

腾讯安全云鼎实验室

容器 云安全 白皮书

Flink 实践教程-入门(5):写入 ClickHouse

腾讯云大数据

流计算 Oceanus

正向代理和反向代理

liuzhen007

11月日更

IOS技术分享| WebRTC iOS源码下载&编译

anyRTC开发者

ios 音视频 WebRTC 实时通信 视频直播

MapReduce Service更换集群外部时钟源,仅需10步

华为云开发者联盟

大数据 FusionInsight ntp 时钟同步 MapReduce Service

ODC V3.2.0 新版本发布 | 着重用户体验,挑战权限管控业务场景

OceanBase 数据库

数据库 开发者 稳定性 应用场景 新功能

如何快速应对井喷下的OCR需求?

鲸品堂

OCR

Windoes下安装配置flutter环境

坚果

flutter windows 安装 11月日更

【LeetCode】键盘行Java题解

Albert

算法 LeetCode 11月日更

白码低代码/无代码开发平台功能及作用

低代码小观

低代码 开发工具 开发平台 无代码 企业服务

OBCE首位认证 实力与颜值并存 | 90后技术宅郑皓嘉的通关之路

OceanBase 数据库

分布式数据库 认证 oceanbase OBCE

Sentinel-Go 源码系列(二)|初始化流程和责任链设计模式

捉虫大师

sentinel Go 语言 sentinel-go

在IntelliJ IDEA中,开发一个摸鱼看书插件

小傅哥

Java 小傅哥 IDEA idea插件

OceanBase 源码解读(六):存储引擎详解

OceanBase 数据库

数据库 开发者 高性能 资源隔离 租户

解放重复劳动丨华为云IoT API Explorer对接小程序实现系统化应用

华为云开发者联盟

小程序 App IoT 华为云 API Explorer

深入剖析 RocketMQ 源码 - 消息存储模块

vivo互联网技术

RocketMQ 微服务 中间件 消息队列

CSS页面设计稿构思与实现(一)

Augus

CSS 11月日更

【Flutter 专题】14 图解 ListView 不同样式 item 及 Widget 显隐性

阿策小和尚

Flutter 小菜 0 基础学习 Flutter Android 小菜鸟 11月日更

爬虫120例之第17例,用Python面向对象的思路,采集各种精彩句子

梦想橡皮擦

11月日更

架构训练营毕业总结

SAKIN

这场蝴蝶效应,从“丝滑”的双11开始

脑极体

Hive SQL优化思路

大数据技术指南

11月日更

为何我中断执行的线程不起作用,Why

华为云开发者联盟

Java 线程 对象 中断

TDSQL | 在整个技术解决方案中HTAP对应的混合交易以及分析系统应该如何实现?

腾讯云数据库

tdsql 国产数据库

你以为委派模式很神秘,其实你每天都在用

Tom弹架构

Java 架构 设计模式

dart系列之:dart语言中的函数

程序那些事

flutter 后端 dart 程序那些事 11月日更

Flink 的状态管理实践

五分钟学大数据

flink 11月日更

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