NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

C#的未来:追踪空引用

  • 2015-04-29
  • 本文字数:1400 字

    阅读完需:约 5 分钟

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

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

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

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

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

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

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

类型转换

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

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

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

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

构造函数

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

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

混合新代码与遗留代码

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

关于可空引用的更多内容

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

其它问题

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

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

2015-04-29 09:022016
用户头像

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

关注

评论

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

深入探索编译插桩技术(三、解密 JVM 字节码,都是精髓

android 程序员 移动开发

疫情下,每个职场人都要思考这4点,有了这些中高端面试专题-大厂还会远吗

android 程序员 移动开发

疫情之下,这真是一份完美的程序员宅家指南,androidsdk开发实例

android 程序员 移动开发

炸裂!万字长文拿下HTTP 我在鹅厂等你!,入职阿里啦

android 程序员 移动开发

王者荣耀MVP-不不不,一个小例子彻底搞懂Android的-MVP到底是什么

android 程序员 移动开发

深入浅出,Andorid 端屏幕采集技术实践(1),android面试题整理最新

android 程序员 移动开发

熟悉Android打包编译的流程,超硬核

android 程序员 移动开发

玩转Android事件分发机制,kotlinnative内存管理

android 程序员 移动开发

由浅入深理解Android虚拟机—内存模型,垃圾回收机制是如何实现的

android 程序员 移动开发

深入RecyclerView学习—缓存机制,kotlin带参数的单例模式

android 程序员 移动开发

深入理解 RecyclerView 的绘制流程和滑动原理,android应用开发教程答案

android 程序员 移动开发

深入理解Flutter动画原理,安卓framework

android 程序员 移动开发

深入解析Android的StateListDrawable,【工作感悟】

android 程序员 移动开发

温故知新:深入理解Android插件化技术,Android高级插件化强化实战

android 程序员 移动开发

独立开发者为什么,不需要运营也能月薪几万,甚至几十万?

android 程序员 移动开发

疫情下中年IT的焦虑,轻松拿下offer

android 程序员 移动开发

深入Flutter TextField,android开发流程图

android 程序员 移动开发

深入浅出:MVVM+ViewBinding,互联网寒冬公司倒闭后

android 程序员 移动开发

热修复——Tinker的集成与使用,android系统工程师面试题

android 程序员 移动开发

深入探索 Android 内存优化(炼狱级别-上),安卓消息分发机制

android 程序员 移动开发

深入探索 Android 网络优化(二、网络优化基础篇,移动开发框架

android 程序员 移动开发

热修复设计之热修复原理(三),kotlin后端框架

android 程序员 移动开发

深入浅出,Andorid 端屏幕采集技术实践,附大厂真题面经

android 程序员 移动开发

用最通俗简单的方式,带你全面理解Android事件传递机制,有一句废话你砍我

android 程序员 移动开发

疫情下,中年IT的焦虑,Android面试总结

android 程序员 移动开发

疫情让“灵活用工”浮出水面,一线互联网公司面经总结

android 程序员 移动开发

深入学习-Gradle-自动化构建技术(五)Gradle-插件架构实现原理剖析-

android 程序员 移动开发

深入探索 Android 内存优化(炼狱级别-上)(1),2021年最新Android面试点梳理

android 程序员 移动开发

滴滴DoKit Android核心原理揭秘之函数耗时,android组件化

android 程序员 移动开发

炸裂!万字长文拿下HTTP 我在鹅厂等你!(1),html5移动开发框架

android 程序员 移动开发

疫情结束后,会影响程序员年后找工作吗?,安卓开发面试题自定义view

android 程序员 移动开发

C#的未来:追踪空引用_C#_Jonathan Allen_InfoQ精选文章