当前位置: 首页 > news >正文

未来的C#之覆写放宽

能使用协变(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

相关文章:

  • 《机器人爱好者(第2辑)》——Robot Hut初印象
  • 《Linux指令从入门到精通》——4.2 Linux下的简单文字模式文本编辑器
  • Java 获取当前操作系统信息
  • import static和import的区别(转)
  • 程序员再回首
  • MYSQL坑爹的UPDATE子查询,UPDATE时避免使用子查询
  • R数据可视化----ggplot2之标度、坐标轴和图例详解
  • 深入解析SQL Server并行执行原理及实践(上) ---高继伟
  • 关于在a标签中添加点击事件的一些问题
  • Hbase 布隆过滤器BloomFilter介绍
  • E: Sub-process /usr/bin/dpkg returned an error code (1)错误解决
  • Maven属性(properties)标签的使用
  • 微信小程序开发(1) 天气预报
  • 爱情的餐桌-作家张小娴
  • NodeJs之fs的读写删移监块
  • 【技术性】Search知识
  • Android交互
  • Cookie 在前端中的实践
  • docker容器内的网络抓包
  • Java多线程(4):使用线程池执行定时任务
  • JS学习笔记——闭包
  • Python打包系统简单入门
  • SAP云平台运行环境Cloud Foundry和Neo的区别
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 数据结构java版之冒泡排序及优化
  • 问题之ssh中Host key verification failed的解决
  • 我的面试准备过程--容器(更新中)
  • 小而合理的前端理论:rscss和rsjs
  • 阿里云移动端播放器高级功能介绍
  • ​ubuntu下安装kvm虚拟机
  • ​马来语翻译中文去哪比较好?
  • !!java web学习笔记(一到五)
  • #if和#ifdef区别
  • #每天一道面试题# 什么是MySQL的回表查询
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • $NOIp2018$劝退记
  • (02)Hive SQL编译成MapReduce任务的过程
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (Python) SOAP Web Service (HTTP POST)
  • (Redis使用系列) Springboot 实现Redis消息的订阅与分布 四
  • (分布式缓存)Redis持久化
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (学习日记)2024.02.29:UCOSIII第二节
  • (转)http协议
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • (转载)OpenStack Hacker养成指南
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容
  • .NET Core WebAPI中封装Swagger配置
  • .NET Framework .NET Core与 .NET 的区别
  • .NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖
  • .net 托管代码与非托管代码
  • /var/log/cvslog 太大
  • [20160902]rm -rf的惨案.txt
  • [AAuto]给百宝箱增加娱乐功能