直播预约通道开启!2021腾讯数字生态大会邀您共探产业发展新机遇! 了解详情
写点什么

C#的未来:追踪空引用

2015 年 4 月 29 日

在.NET 中最常见的错误类型大概要数空引用异常了。这个错误的根源在于 C#无法表达出非空引用的概念,这也导致让编译器强制进行空检查变成一种过于繁重的任务。

为了应对这个问题,某条提议建议使用一种强制引用,以及一种明确的可空引用的定义。在提议中,可空引用将使用? 后缀进行定义,正如可空值类型的定义方式一样。而强制引用,或者说非空引用将使用! 后缀进行定义。

强制引用以及可空引用都应该被视为一种仅限于语言本身的概念,它们只是改变了编译器的行为,但不会改动所生成的 IL 代码。

在编译器允许访问可空引用对象的任何方法或属性之前,必须明确地检查空引用。并且在将某个可空引用转型为强制引用之前,也必须对空引用进行检查。

强制引用需要编译器证实其中包含的值不可为空。由于这是一种仅限于编译器的规则,因此无法保证在反序列化等场景中能够同样生效。

在阅读这条提议的完整内容时,你会注意到其中提到的某个术语“一般引用”。它指的是 C#中的普通引用,它既不是强制的,也不是明确定义为可空的。由于这种引用将被视为遗留代码,因此可以通过 AllowGeneralReferences 这一属性告诉编译器不允许在代码中使用一般引用。

在结合隐式变量定义时,可以在 var 关键字中使用! 或? 后缀。

类型转换

根据这条提议,你可以隐式地将某个强制引用转换为可空引用。不过,它不允许你将某个一般引用转换为可空引用,对此有如下的解释:

假设一下这个一般引用的意图(或许它从概念上来说应当是强制的,而不是一种可空的概念)。

但这种说法是没有什么道理的,如果某个实际的强制引用能够隐式地转换为可空引用,那么某个“概念性的强制引用”应该也可以实现这一转换。

与之类似的是,从强制引用或可空引用转换为一般引用也是不允许的,这也是基于同样的理由,尽管该理由存在着一些疑问。

构造函数

对于非空引用类型的这一提议中还存在着一条有待解决的问题,那就是很难在构造函数中强制这种非空性。对此,有一条提议就是不要处理这一问题。就像我们在构造函数中可以多次为某个“只读”字段进行赋值一样,我们可以直接声明这条规则在构造函数中并不生效,需要开发者本人注意到这一点。

这条提议乍一看起来会产生反效果,但它实际上是很有道理的。开发者们在构造函数中本来就需要注意访问可能尚未初始化的字段会带来的问题。这一条提议也没有改变这一现象,如果开发者忽略了这一点,那么构造函数就会产生错误,而这将减少出现空引用异常的风险。

混合新代码与遗留代码

非空引用这条提议还需要面对另一个问题,那就是如何处理遗留代码。比方说,如果已经对基础类库进行升级,在其中使用了这个新的语法。而现有的应用程序可能无法立即进行代码的改动,那么必须要有某种机制能够关闭这一新语法的使用。这条提议中提供了一个IgnoreNewStyleReferences 属性,可以通过它忽略某个外部程序集中所使用的新的引用语法。

关于可空引用的更多内容

在前文中,我们提到过可空引用可能会处于两种状态之一:未知或判定为非空(注:也可能判定为空)。这条提议对此进一步说明,如果某个引用已经判定为空,那么在之后的代码中就无法使用它(赋值给另一个可空变量),开发者必须使用一个硬编码的空值,这也能够让代码的意图表现得更加清晰。

其它问题

这一提议还有许多需要处理的问题。比方说,是否能够定义强制引用的数组?在使用反射时如何暴露强制引用与非空引用?它们与泛型之间又将如何交互?

查看英文原文: C# Futures: Nullability Tracking

2015 年 4 月 29 日 09:021711
用户头像

发布了 428 篇内容, 共 152.8 次阅读, 收获喜欢 26 次。

关注

评论

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

阿里面经最新分享:Java面试指南/成长笔记(金三银四程序员必备)

比伯

Java 编程 程序员 架构 面试

区块链药品溯源解决方案-区块链技术监管医药溯源

13530558032

《不看后悔》38个JVM精选问答,让你变成专家

云流

Java 架构 面试 JVM虚拟机原理

用c++创作一个简单小游戏

张鹤羽粑粑

28天写作 3月日更

简单工厂模式、工厂模式、抽象工厂模式比较

良知犹存

设计模式

连肝26天,熬夜拜读349页阿里面试通关手册,成功闯进字节跳动

互联网架构师小马

Java 编程 面试 求职 找工作

【回溯算法】借助最后一道「组合总和」问题来总结一下回溯算法 ...

宫水三叶的刷题日记

LeetCode 数据结构与算法 面试数据结构与算法

【金三银四】这才是打开Java面试的正确方式,吃透这份【Java面试手册】offer稳了

云流

Java 编程 面试

程序员必须知道的数据结构:线性表与链表

老王说编程

Java 链表 线性表

微信团队分享:微信直播聊天室单房间1500万在线的消息架构演进之路

JackJiang

微信 架构设计 即时通讯

Elasticsearch Index Types and Mappings

escray

elastic 七日更 28天写作 死磕Elasticsearch 60天通过Elastic认证考试 3月日更

萌新不看会后悔的C++基本类型总结(二)

花狗Fdog

LeetCode题解:714. 买卖股票的最佳时机含手续费,动态规划,JavaScript,详细注释

Lee Chen

算法 LeetCode 前端进阶训练营

程序员必须知道的数据结构:队列与栈

老王说编程

数据结构 队列

智慧党建系统开发,智慧组工平台建设

13530558032

饿了么刚给我确认了p7的职位,对自己的经历,做一个面试总结。

Java架构之路

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

力扣(LeetCode)刷题,简单题(第21期)

不脱发的程序猿

LeetCode 面试刷题 28天写作 算法面经 3月日更

Flutter 2 来了

SamGo

flutter

Wireshark数据包分析学习笔记Day3

穿过生命散发芬芳

Wireshark 数据包分析 3月日更

恋物志(二):独居者的智能生活指南

脑极体

Redis 与 I/O 多路复用模型

学个球

redis

程序员必须知道的数据结构:HashMap 与 LinkedHashMap

老王说编程

Java 数据结构 hashmap

简易项目搭建 Models层封装

happlyfox

学习 28天写作 3月日更

总结近期腾讯+阿里+百度Java岗高频面试题,提问率高达98%,看到这篇文章基本offer稳了

Java架构之路

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

两会热词“区块链”,打开传统溯源的一扇大门!

源中瑞-龙先生

区块链 两会

mock 请求分发

blueju

JavaScript React Mock umi umijs

开源镜像仓库Harbor的镜像安全

运维研习社

Docker Harbor 漏洞扫描 镜像安全 私有仓库

金三银四程序员面试必备:2021最新 最全面Java复习路线!已收录GitHub

比伯

Java 编程 程序员 架构 面试

Oracle table()函数的合理运用,提高工作效率

xiezhr

oracle table() Oracle函数 3月日更

2021普通Java程序员如何在行业中脱颖而出?阿里进阶架构师不传之秘终于开源!

程序员小毕

Java 程序员 架构 面试 分布式

正则表达式.01 - 元字符

insight

正则表达式 3月日更

技术为帆,纵横四海- Lazada技术东南亚探索和成长之旅

技术为帆,纵横四海- Lazada技术东南亚探索和成长之旅

C#的未来:追踪空引用-InfoQ