写点什么

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

评论

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

java程序员的AI之路-大数据篇 hadoop安装,java基础知识点梳理

Java 程序员 后端

Java笔记 —— Set集合的排序原理,附答案+考点

Java 程序员 后端

模块二作业

迪马

Java类的继承与组合经典实例,java自学教程百度云盘

Java 程序员 后端

Java系列高频面试题:序列化+注解,java基础入门第二版电子书

Java 程序员 后端

腾讯数字生态大会|大数据与你相约武汉

腾讯云大数据

大数据

Java版流媒体编解码和图像处理(JavaCPP+FFmpeg)

Java 程序员 后端

Java程序员必须熟记的微服务面试题(含答案)

Java 程序员 后端

Java程序员裸辞两个月,面试阿里、美团,值得一读

Java 程序员 后端

Flink 实践教程:入门(3):读取 MySQL 数据

腾讯云大数据

flink 流计算 Oceanus

Java笔记 —— IO,java定时任务quartz面试

Java 程序员 后端

Java虚拟机(JVM)面试题(2020最新版),linux视频教程下载

Java 程序员 后端

Java死锁的原因例子及解决方法,三年Java开发

Java 程序员 后端

Java程序员的工资为什么那么高,首先要先掌握这999页阿里P8笔记!

Java 程序员 后端

Java程序员(阿里、京东,java系统架构设计详解

Java 程序员 后端

Java程序员:面试字节跳动被问算法 多亏我扛下来了

Java 程序员 后端

机器学习在基于源码的漏洞挖掘中的应用

maijun

机器学习 静态代码分析 源码漏洞挖掘 code embedding

Java架构师面试问些什么?微服务之springcloud面试题(共22题

Java 程序员 后端

Java注解,java架构师课程哪家好

Java 程序员 后端

架构实战营第 1 期 - 毕业总结

Anyou Liu

「架构实战营」

Java进阶之梯,成长路线与学习资料,助力突破中间件领域

Java 程序员 后端

Java的wait和notify学习三部曲之一:JVM源码分析

Java 程序员 后端

Java程序员极力推荐的springboot全家桶干货系列

Java 程序员 后端

Java程序员经典面试题集大全(一),分享面试经历的网站

Java 程序员 后端

Flink 实践教程:入门(2):写入 Elasticsearch

腾讯云大数据

flink 流计算 Oceanus

Flink 实践教程:入门(1):零基础用户实现简单 Flink 任务

腾讯云大数据

flink 流计算 Oceanus

040022-week2-design

InfoQ_70156470130f

Java注解-一文就懂,java程序设计与实践教程王薇

Java 程序员 后端

Java知识体系总结(2021版),JDK、JRE与JVM的区别与联系

Java 程序员 后端

java程序员的AI之路-大数据篇 hadoop安装(1)

Java 程序员 后端

java继承和多态,Java开发岗笔试题

Java 程序员 后端

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