写点什么

未来的 C#之覆写放宽

  • 2017-05-02
  • 本文字数:1259 字

    阅读完需:约 4 分钟

能使用协变(covariant)返回类型,这是一个在.NET 中常被请求到的特性。例如,可以使用“override Widget Clone()”覆写“virtual object Clone()”。从类型安全的角度看,这种做法完全可以接受,但是当前并不被 C#所允许。

根据“对协变返回类型的建议”,该规则将被放宽,使得相比于基类中的方法,子类中的同一方法可以返回更具体的类型。除了上例中给出的 Clone 方法之外,这种放宽对抽象工厂和其他框架代码也会十分有用。

隐式投影(Implicit Shadowing) 在 C#中,一种可能的实现方法是发射(Emit)两个函数。还以 Clone 方法为例,我们可以在中间语言(IL)中看到如下的方法签名(Method Signature):

复制代码
override object Clonable.Clone()
public new Widget Clone()

按 HaloFour 的说法,这是可以工作的,原因在于:

在通用语言运行库(CLR,Common Language Runtime)规范中,看上去的确允许覆写具有不同的名字,并可以具有不同的可见性(Visibility)。

[…]

通过在 IL 中显式地使用“.override”语句,我能解决所有的重载决议(Overload Resolution)问题,并能使用具有不同可见性和名字的方法进行覆写。

该编译器特性可与现有的 CLR 版本无缝工作,并且旧版本的 VB 或 C#将可以毫无问题地消费这样的类。

但是这一做法也存在着一些限制。首先,从覆写方法正常继承而来的属性是不能被拷贝到隐藏(New)方法中的。从技术上讲,编译器可以拷贝基类属性到隐藏方法上。但是这种做法存在着问题,一旦添加隐藏属性添加到基类方法,就将需要对子类进行重编译。

其次,这也会导致在使用反射(Reflection)时,难以看到隐藏方法与被覆写的基类方法之间的关联。

最后一点,这会对通过基类接口的调用方法产生性能上的影响。但是,该问题可以通过尾调用(Tail Call)及其他优化技术缓解。

属性

在 C#中,另一种可能的实现方法是使用新属性。如果编译器能识别该属性,则会针对更具体的类型自动添加强制转换(Cast)。

该方法的一个缺点在于,如果新属性不能被语言所理解,就不能使用该方法。当然,新属性也必须添加到基础类库(BLC,Base Class Library)中,这意味着它不会在所有的平台上立刻可用。

另一个缺点是,它可能会在处理结构体时引入不必要的装箱(Boxing)操作。继续以上面的 Clone 方法为例,编译器将必须装箱一个 WidgerStruct 结构体,然后立刻将其强制转换为一个正常的 WidgetStruct 结构体。

投影和覆写的放宽

另一种替代做法是放宽对投影的限制规则。当前,一个方法是不允许同时被投影和覆写的。但是,考虑到 CLR 是支持这种做法的,C#只是允许显式地编写如下代码:

复制代码
class Widget : Cloneable
{
public override Cloneable Clone()
{
return this.Clone();
}
public new Widget Clone()
{
return [...];
}
}

根据隐式投影的建议,这将依赖编译器去重命名重载方法。

时间表

需要指出的是,大部分该特性相关的讨论出现于 2015 年上半年,即两年之前。但是该建议是在今年二月份才正式写完,因此尚未采取任何行动,或者说尚未公开采取任何行动。

查看英文原文: C# Futures: Relaxed Overrides

2017-05-02 19:001828
用户头像

发布了 227 篇内容, 共 82.5 次阅读, 收获喜欢 28 次。

关注

评论

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

架构师第8周作业

Geek_xq

技术创新是PC市场发展基石,英特尔占据明显领先优势

E科讯

区块链2021狂想曲:迎接以技术为名的春天

脑极体

极客训练营知识点思维导图

jorden wang

GitHub标星150K的神仙笔记,3个月肝完成功面进美团定级3-2

Java架构之路

Java 程序员 架构 面试 编程语言

安卓开发实战!闭关在家37天“吃透”这份345页PDF,成功定级腾讯T3-2

欢喜学安卓

android 程序员 面试 移动开发

使用 kubectl-rabbitmq 部署和运维 K8S 上的 RabbitMQ 集群

郭旭东

RabbitMQ kubectl kubectl plugin

百度面试被算法血虐,闭关29天肝完445页算法神仙笔记成功入职字节跳动!

Java架构之路

Java 程序员 架构 面试 编程语言

架构师训练营第十三周笔记

李日盛

笔记

APICloud AVM多端开发 |《生鲜电商app开发》项目源码教程

YonBuilder低代码开发平台

大前端 移动开发 APP开发 APICloud

在GitHub中向开源项目提交PR的过程

worry

GitHub pull request

PHP转JAVA开发30分钟实战攻略

dothetrick

Java php

训练营第十三周作业

大脸猫

电商网站商品管理(二)多种搜索方式

escray

elasticsearch elastic 28天写作 死磕Elasticsearch 60天通过Elastic认证考试

技术人员如何写好周报

猿话

[5/28]产品运维保障体系的质量实践

L3C老司机

我们为什么打比方

石云升

28天写作 确认偏误 打比方

Nginx 的负载均衡模式有哪些?它的实现原理是什么?

李尚智

nginx 架构 微服务

2021年,字节/百度/阿里相继发布50W+优质Java岗(含内部面试真题及答案)

996小迁

Java 程序员 架构 面试

矿机挖矿软件系统开发|矿机挖矿APP开发

系统开发

一文带你学会AQS和并发工具类的关系

伯阳

AQS java 并发 ReentrantLock 多线程高并发 lock锁

【得物技术】代码覆盖率原理与得物app实践

得物技术

测试 原理 代码 得物技术 覆盖率

9. 细节见真章,Formatter注册中心的设计很讨巧

YourBatman

Converter ConversionService Formatter

从姚安娜出道说起

三只猫

28天写作 社交泛娱乐

架构师第八周总结

Geek_xq

2021字节、华为、滴滴Java内部面试题(含答案),新鲜出炉!

比伯

Java 编程 架构 面试 程序人生

超越身边80%的人,其实没有你想象的那么难

架构精进之路

认知提升 成长笔记 七日更 28天写作

为什么印度不会成为世界工厂?

JiangX

印度 28天写作 世界工厂

Java 程序经验小结:剖析@SuppressWarinings注解

后台技术汇

28天写作

华云大咖说|企业混合云构建之道

华云数据

云计算 桌面云

二本学渣考研失败,为什么Android要采用Binder作为IPC机制?已开源

欢喜学安卓

android 程序员 面试 移动开发

未来的C#之覆写放宽_.NET_Jonathan Allen_InfoQ精选文章