在 2025 收官前,看清 Data + AI 的真实走向,点击查看 BUILD 大会精华版 了解详情
写点什么

C#的未来:追踪空引用

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

    阅读完需:约 5 分钟

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

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

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

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

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

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

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

类型转换

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

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

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

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

构造函数

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

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

混合新代码与遗留代码

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

关于可空引用的更多内容

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

其它问题

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

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

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

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

关注

评论

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

Java学习书籍推荐!

程序员高级码农

Java 程序员 计算机

《算法导论(第4版)》阅读笔记:p173-p174

codists

算法

1688店铺订单接口指南攻略

tbapi

1688订单物流接口 1688店铺订单接口 1688店铺订单详情接口

Redis 集群操作配置(超详细配图,配截图详细说明)

量贩潮汐·WholesaleTide

redis

互联网大厂1000道Java面试题及答案整理

Geek_Yin

Java 程序员 Java面试题 Java面试八股文

【HarmonyOS 5】鸿蒙中的UIAbility详解(一)

GeorgeGcs

华为开发者空间 - MindSpore魔法课堂:手把手教你玩转AI框架

华为云开发者联盟

Jupyter Notebook 昇思MindSpore AI‘’ 华为开发者空间

2025年中高级JAVA工程师面试题汇总

Geek_Yin

Java 编程 Java面试题 Java面试八股文

【HarmonyOS 5】鸿蒙中的UIAbility详解(二)

GeorgeGcs

鲲鹏Arm+麒麟V10,国产化信创 K8s 离线部署保姆级教程

北京好雨科技有限公司

k8s rainbond 容器平台 企业号 5 月 PK 榜 信创国产化

华为浏览器上线高考频道,打造一站式智慧助考服务

最新动态

Web端实时通信技术SSE在携程机票业务中的实践应用

JackJiang

网络编程 即时通讯 IM

[大厂实践] LLM加速大规模测试迁移

俞凡

人工智能 测试

Shiro简介及SpringBoot集成Shiro(狂神说视频简易版)

刘大猫

人工智能 算法 数据分析 权限控制 shiro

HAProxy 可观测性最佳实践

观测云

HAProxy

明基专业编程显示屏618优惠,程序员入手就趁现在!

陈老老老板

基于YOLOv8的汽车车牌位置实时检测项目【完整源码数据集+PyQt5界面+完整训练流程+开箱即用!】

申公豹

yolov8

鸿蒙仓颉语言开发教程:自定义弹窗

幽蓝计划

1688商品评论API接口攻略

tbapi

1688商品评论接口 1688评论API 1688评论数据采集

时序数据库 Apache IoTDB V2.0.3 发布|新增元数据导入导出脚本适配表模型功能

Apache IoTDB

全新小艺上车鸿蒙智行尊界S800,启领智慧出行新范式

极客天地

是时候跟虚拟机说再见了?

北京好雨科技有限公司

k8s rainbond 容器平台 企业号 5 月 PK 榜 信创国产化

DeepSeek‑R1-0528 重磅升级:蚂蚁百宝箱免费、无限量调用

猫头虎

人工智能 DeepSeek DeepSeek v3 DeepSeek R1 模型

鸿蒙仓颉语言开发实战教程:实现商品分类页

幽蓝计划

Redis 数据恢复的月光宝盒,闪回到任意指定时间

Baidu AICLOUD

数据库 redis

今年夏天,最不该错过的一场 AI 聚会

RTE开发者社区

5 分钟搞定 Go 自定义结构体标签

俞凡

golang

【HarmonyOS 5】Laya游戏如何鸿蒙构建发布详解

GeorgeGcs

H5 HarmonyOS 小游戏 Laya 构建鸿蒙

【HarmonyOS 5】鸿蒙中的UIAbility详解(三)

GeorgeGcs

从试验田到深水区,AI落地的福州答卷

脑极体

AI

SpringBoot项目的html页面使用axios进行get post请求

刘大猫

人工智能 算法 post GET axios

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