写点什么

C#将引入可空的引用类型

  • 2017-04-20
  • 本文字数:1360 字

    阅读完需:约 4 分钟

是的,标题没错。C#其中一份新提案假定,所有的引用类型在默认情况下都是不可空的。在新语法下,你需要显式地标明一个引用变量是可空的,就像对值类型所做的那样。

和值类型一样,T 是指不可空类型,而 T? 是指可空类型。以下情况会产生警告:

  • 取消对可空变量的引用;
  • 一个可空变量或参数被赋值给一个不可空变量;
  • 从 T?[] 转换到 T[];
  • 从 T[] 转换到 T?[];
  • 将一个空字面量赋值给一个不可空变量或参数;
  • 构造函数没有给所有的不可空字段赋值;

对于前两种情况,如果你使用了感叹号运算符(x!)或者编译器能够证明已经执行了 null 检查,那么警告将被忽略。

实现细节

底层编译器将会忽略可空注解,因此,那不是问题。不过,在程序集级,应该有某种标记,可以说明库在编译时启用了可空注解。

由于所有这类可空的东西从技术上讲都是一种破坏性修改,所以当前的计划是允许开发人员选择下面的类别:

  • 可空警告;
  • 不可空警告;
  • 警告来自其他文件中的注解。

提案继续写道:

选择参与的粒度表明,这是一个类似分析器的模型,大段的代码通过编译指令选择参与和退出,用户可以选择安全级别。此外,每个库的选项(“在准备好应对后果之前,忽略 JSON.NET 中的注解”)可以表示为代码中的属性。

根据预期,这种设计要达到以下三个目的:

  • 用户可以像他们希望的那样逐步采用可空属性检查;
  • 库作者可以添加可空属性注解,而不必担心破坏用户的代码;
  • 除此之外,没有“配置噩梦”之感。

对于同一个方法,你不必进行可空和不可空的重载。虽然从技术上讲,CLR 支持这样做,但那不是 CLS 或者通用语言规范的组成部分。这意味着,大多数编译器都会不知道发生了什么。HaloFour 作了如下说明:

modreq不是 CLS。modopt确实支持重载,但需要具体了解所有重要编译器的这个部分,因为至少要将修饰符复制到调用签名里。两者都会破坏与现有方法签名的兼容。对于希望在整个 BCL 快速传播的东西来说,使用modopt会成为巨大的障碍。

泛型

在使用泛型时,以下情况会出现额外的警告:

  • 从 C转换到 C<T?>,除非类型参数是协变量(出);
  • 从 C<T?> 转换到 C,除非类型参数是反变量(入);
  • 使用 C<T?>,然后将类型参数限制为不可为空。

使用“class”,则泛型强制非空。使用“class?”则允许空值。该提案继续写道:

如果一个类型参数没有约束,或者只有可空约束,则情况会稍微复杂一些:这意味着,相应的类型参数既可以为空,也可以不为空。在那种情况下,安全的做法是将类型参数既作为可空参数来处理,又作为不可空参数来处理,任何一个不满足,就发出警告。

数组

数组是一项特殊的挑战,因为在一个不可为空的数组中,不一定可以确保每个槽都有一个值。

对于一个非空引用数组,我们无法通过充分地跟踪来保证数组的所有元素都被初始化。不过,在从数组读取数据或者传递数组之前,如果新创建的数组没有元素被赋值,我们就会发出警告。那应该可以处理常见的情况,而又不带来太多干扰。

开放性设计问题

使用 default(T) 应该发出警告吗?还是说假定它会返回 T?,而不是 T?

可以删除局部变量上的? 而根据使用情况推断其可空性吗?

参数可以使用 T! x 模式自动生成 null 检查吗?

可以调整一下可空值类型,以便让开发人员可以使用 x.method 代替 x.Value.method 吗(这用在当 x 已知非空时,比如已经成功完成了 null 检查)?

更多信息

查看英文原文: C# Futures: Nullable Reference Types

2017-04-20 18:162356
用户头像

发布了 1008 篇内容, 共 441.2 次阅读, 收获喜欢 346 次。

关注

评论

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

云解析的智能线路是什么意思?有什么实际用途?

防火墙后吃泡面

Go语言中高效使用Redis的Pipeline

左诗右码

Go

第二届海南大数据创新应用大赛 - 算法赛道冠军比赛攻略_海南新境界队

阿里云天池

重磅:香港大学经管学院副院长沈海鹏博士出任望繁信科技首席顾问!

望繁信科技

大数据 数字化转型 流程挖掘 流程智能

D2O 前置放大器仿真插件(Triton Audio D2O mac版下载安装)

Rose

Tomcat源码分析 (一)----- 手撕Java Web服务器需要准备哪些工作

派大星

tomcat源码解读

鲁棒性目标检测 TOP2 方案分享

阿里云天池

4大要点助你选择室内LED显示屏

Dylan

LED显示屏 全彩LED显示屏 led显示屏厂家 户内led显示屏

和鲸携手山东大学数字人文实验室,推动新文科与人工智能融合发展

ModelWhale

探索顶级PDF水印API:PDFBlocks(2024年更新)

幂简集成

API PDF水印

TapData 信创数据源 | 国产信创数据库 TDengine 数据同步指南,加速国产化进程,推进自主创新建设

tapdata

公链大变局:ETH老态龙钟,SOL势如破竹

区块链软件开发推广运营

交易所开发 dapp开发 区块链开发 NFT开发 公链开发

Optical Flares插件怎么安装?Optical Flares中文汉化版详细安装教程

Rose

中文版Nik Collection 6 滤镜插件套装 适用于ps/lr

Rose

Nik Collection 6 滤镜

photoshop阴影插件 Shadowify 苹果Mac版

Rose

ps阴影插件 Shadowify

FCPX插件:MotionVFX - mWedding 2 盛大的婚礼效果

Rose

行云堡垒V7.4新特性

行云管家

3款让工作效率翻倍的神器!一键轻松搞定PDF转PPT!

职场工具箱

效率工具 职场 PPT 办公软件 AI生成PPT

Coze插件发布!PDF转Markdown功能便捷集成,打造你的专属智能体

合合技术团队

人工智能 PDF

使用代理IP有风险吗?

IPIDEA全球HTTP

代理IP

行云堡垒-幽影护企业数据安全!

行云管家

数字化 数据安全 企业数据

一汽集团数据专家分享:实时数据技术在汽车行业的应用与实践经验

tapdata

郑雁鹏|浅谈工业实时数据库和时序数据库的关系

麦杰研究院

数据库 工业实时数据库 工业时序数据库 麦杰科技 麦杰研究院

【YashanDB知识库】共享集群YAC换IP

YashanDB

yashandb 崖山数据库 崖山DB

测试环境治理之MYSQL索引优化篇

京东科技开发者

C#将引入可空的引用类型_.NET_Jonathan Allen_InfoQ精选文章