写点什么

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

评论

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

北鲲云SaaS平台为生物制药研发进程带来“加速度”

北鲲云

围绕低代码开发存在的三个误解

低代码小观

程序员 低代码 企业管理 低代码开发平台 应用开发

40 个 SpringBoot 常用注解:让生产力爆表

Java 面试 框架 Spring Boot 2

坚持客户第一!

鉴释

产品研发 静态代码分析

花了3个小时解决了和异地女朋友一起看电影的需求(内附源码)

ZEGO即构

android 音视频 一起看电影

相约重庆,2021 DEMO CHINA创新中国峰会倒计时六天

创业邦

博睿数据赋能数字化转型,用户体验升级需要有“温度”的技术

博睿数据

【OpenIM原创】IM服务端docker、源码、集群部署 非常实用

OpenIM

让全链路压测变得更简单!Takin2.0重磅来袭!

TakinTalks稳定性社区

Alibaba 80k Star《Java面试突击手册》(全彩版)开源

Java 程序员 架构 面试 计算机

WorkPlus即时通讯软件,满足政企局域网办公需求

BeeWorks

Javacv 音视频小工具 - 下载抖音视频

RTE开发者社区

Java 音视频 ffmpeg javacv

开源应用中心|这款小而强大的开源博客程序,简直让人爱不释手!

开源

【Vuex 源码学习】第五篇 - Vuex 中 Mutations 和 Actions 的实现

Brave

源码 vuex 9月日更

【IM开源推荐】前微信技术专家打造的开源的即时通讯组件OpenIM

OpenIM

2021年8月券商App行情刷新及交易体验评测报告

博睿数据

2021智博会全国区块链大赛暨首届“星火杯”区块链应用大赛正式启动

云计算,

软件测试工程师应该怎样规划自己

程序员阿沐

程序员 职业规划 软件测试 自动化测试 经验分享

财经违规自媒体集体扑街,必须打击违规自媒体账号

石头IT视角

观测云品牌正式亮相,携手中国信通院共推国内可观测性概念与技术发展!

观测云

区块链是如何运作的、是如何防止被篡改的?

CECBC

集齐海外主流云平台,EMQ X Cloud 正式支持 Google Cloud Platform 部署

EMQ映云科技

IoT Google Cloud AIOT 云 原生云 CTO

ONNX 浅析:如何加速深度学习算法工程化?

拍乐云Pano

人工智能 深度学习 音视频

WeTest21年焕新钜惠活动福利你领到了吗?

WeTest

等保三级多久测评一次?每年都要测评吗?

行云管家

网络安全 信息安全 等保

自动化驱动的高可用网络:爱奇艺B2网络流量自动调度系统建设实践

爱奇艺技术产品团队

流量

到底什么是区块链?是咋样的运营原理

CECBC

重磅发布!百度飞桨获2021全球智博会产品金奖

百度大脑

人工智能

Android如何用代码执行shell命令

Changing Lin

9月日更

Alibaba iOS 工程架构腐化治理实践

阿里巴巴终端技术

ios 研发效能 客户端 架构治理

使用分布式锁的正确姿势

张大彪

分布式锁

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