写点什么

未来的 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:001781
用户头像

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

关注

评论

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

突破四大要素  飞算SoFlu助力企业实现DevOps落地

飞算JavaAI开发助手

DevOps 自动化 软件工程

Vue进阶(八十六):iframe 结合 window.postMessage 实现跨域通信

No Silver Bullet

Vue 8月日更 iframe

互动直播应用快速开发实践(基于声网)

大伟

解析ThreadPoolExecutor类是如何保证线程池正确运行的

华为云开发者联盟

线程池 任务 注释 Worker类

故事点数VS工时,研发工作量到底怎么算?

LigaAI

敏捷开发 故事点数 工时 研发工作量

数仓出现“wait in ccn queue”的时候,怎么迅速定位处理?

华为云开发者联盟

线程 hash 负载 数仓 GaussDB(DWS)

训练千亿参数模型的法宝,昇腾CANN异构计算架构来了~

华为云开发者联盟

盘古 CANN 千亿参数模型 异构计算 计算架构

🏆【Alibaba微服务技术系列】「Dubbo3.0技术专题」回顾Dubbo2.x的技术原理和功能实现及源码分析(温故而知新)

码界西柚

dubbo RPC 8月日更 Dubbo3

Golang并发操作中常见的死锁情形

Regan Yue

协程 Go 语言 8月日更

面试Go语言开发?让这本书帮你感动面试官!

博文视点Broadview

接口测试,负载测试,并发测试,压力测试区别

与风逐梦

软件测试 接口测试

云小课|原来云备份不仅仅是能备份...

华为云开发者联盟

云备份 迁移数据 复制备份

易华录 X ShardingSphere|葫芦 App 后台数据处理的逻辑捷径

SphereEx

数据库 开源

图灵奖得主大全 深度学习经典论文翻译合集 John 易筋 ARTS 打卡 Week 62

John(易筋)

ARTS 打卡计划

最近很火的低代码到底是什么?

禅道项目管理

大前端 测试开发 语言 & 开发

适女化科技(二):让女性更安全的两条技术路径:软件硬件化与硬件软件化

脑极体

最近很火的低代码到底是什么?

禅道项目管理

低代码 可视化 低代码平台

带你走进MySQL全新高可用解决方案-MGR

vivo互联网技术

数据库 分布式 MySQL 高可用

百度信誉认证中台架构解析

百度Geek说

后端 软件架构 中台架构

一个内核漏洞详解:容器逃逸

程序员 架构 面试 计算机

python实现两台不同主机之间进行通信(客户端和服务端)——Socket

Python研究者

8月日更

【浪潮云说】直播间第七期今日准时开播!

云计算运维

国产接口工具ApiPost如何利用CryptoJS对请求参数进行MD5/AES加解密

Proud lion

大前端 后端 加密解密 Postman 接口文档

Hadoop MapReduce原理、序列化

Mike

一起吐槽接口文档

FunTester

接口文档 接口测试 API Jira FunTester

自主创新国产化科技:智能制造之 SMT 产线监控管理可视化

一只数据鲸鱼

数据可视化 工业4.0 制造业 智慧工厂

阿里巴巴新产“Java架构核心宝典”,全是流行技术,限时开放

Java 架构 面试 后端 计算机

信息爆炸!78天闭门深造千页SpringCloud,再战京东

Java~~~

Java spring 架构 面试 Spring Cloud

轮询锁在使用时遇到的问题与解决方案!

王磊

8月日更

CompletableFuture真香,可以替代CountDownLatch!

架构 面试 后端 计算机

开源demo| 视频应用类开源 Demo 大盘点

anyRTC开发者

音视频 视频直播 直播连麦 视频通话

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