写点什么

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

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

关注

评论

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

依赖 jar 没有传递,导致找不到类文件而启动失败了

程序员小航

Java maven

潮玩盲盒系统开发元气部落盲盒app开发

风行无疆

Flutter for Web 在贝壳容灾降级中的应用

贝壳大前端技术团队

flutter 容灾 降级 flutter for web

一张图看懂融云直播 SDK

融云 RongCloud

元宇宙时代的业务、场景、技术机遇探索

融云 RongCloud

融云直播 SDK 2.0 重磅上线,两步接入即可获得视频直播能力

融云 RongCloud

CSS之选择器(六)::before和::after

Augus

CSS 12月日更

微服务架构 | 如何利用好日志链路追踪做性能分析?

李尚智

Java 链路追踪 微服务治理 性能调试 微服务调用链

基于融云直播 SDK,快速实现连麦布局

融云 RongCloud

CODING x 百果园,水果零售龙头迈出 DevOps 体系建设第一步

CODING DevOps

DevOps CODING 百果园 合作

【修复升级】腾讯容器安全首个发布开源 Log4j2 漏洞缓解工具

腾讯安全云鼎实验室

你怎么总是能写出两三千行的controller类?

CRMEB

你想知道的Kotlin version

Changing Lin

12月日更

记录一次win10更新版本后IIS无法启动的解决办法

为自己带盐

28天写作 12月日更

声网把七年无全网事故的实时传输网络SD-RTN全面开放了——这就是FPA!

声网

人工智能 网络 SD-RTN

斗罗大陆真3D手游实力上线,带你感受魂兽猎杀的超燃时刻

华为云开发者联盟

数据库 华为云数据库 rds for mysql 3D手游 PITR

工业企业能耗在线监测系统开发建设

a13823115807

进程ID及进程间的关系

mazhen

Linux Shell Linux Kenel

【软件开发】直播带货App如何开发

青山一叶秋

架构设计之MQ选型

无心水

RocketMQ MQ RabbitMQ Kakfa Activemq

iOS内卷面试题-你以为你够卷了,面试官更卷!

iOSer

ios 内卷 iOS面试

人工成本上升+设备停机率高,制造企业该如何破而后立?

优秀

低代码 制造业

Aeron 是如何实现的?—— Ipc 异常情况处理

BUG侦探

Aeron ipc

可视化神器背后的奥秘

百度开发者中心

大数据 百度开发者沙龙

2021年12月国产数据库排行榜: openGauss节节攀升拿下榜眼,GaussDB与TDSQL你争我夺各进一位

墨天轮

数据库 opengauss TiDB 国产数据库

前端需要的免费在线api接口

德育处主任

JavaScript ajax 前端 Postman API

行云管家荣获第二届国际科创节“2021年度高成长性企业奖”!

行云管家

云计算 混合云 IT运维

解决远程办公安全隐患,就用行云管家!

行云管家

远程办公 IT运维

【HZERO微服务平台6】源码分析之数据权限、sql拦截

qiaoxingxing

签约计划第二季

Flutter流畅度优化神器-开源组件keframe详解

贝壳大前端技术团队

flutter 性能 滑动优化

重磅!中国红十字基金会固生堂中医惠民专项基金成立

E科讯

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