写点什么

C#的未来:简化参数空值验证

  • 2020-01-27
  • 本文字数:1806 字

    阅读完需:约 6 分钟

C#的未来:简化参数空值验证

乍一看,提案#2145似乎是 C# 8 可空引用类型特性的逻辑扩展。其基本思想是,开发人员不需要再显式地向接受非空参数的方法添加参数空值检查。然而,人们对于这个特性的争议很大。


本文试图说明这些选项以及它们的利弊,以便读者能够得出自己的看法。但在此之前,本文将简要说明为什么这在 C# 8 中仍然很重要。


目前,可空引用类型特性只是提供信息。它会警告开发人员在处理空值时的常见错误,但仅在编译时发出警告。当应用程序运行时,所有这些编译时检查都不存在。


此外,在使用反射或 dynamic 时,编译检查根本不起作用。

特定语法:感叹号操作符

原来的建议是使用感叹号操作符!告诉编译器应添加参数空值检查。


//输入的代码void Insert(string value!) {    ...}//编译后的代码void Insert(string value) {    if (value == null)        throw new ArgumentNullException(nameof(value));    ...}
复制代码


这个选项的理由是它破坏性小。它只需要对 C#编译器做一个小的修改,并且新语法完全向后兼容。


反对这一选项的理由是:


  • 它是一种适用面很窄的新语法;

  • 在阅读代码时很容易忽略它;

  • 很容易忘;

  • 声明参数不可为空是多余的。


另一个问题是,value!可能意味着“请检查这个值是否为空”或“不需要检查,我知道它不是空的”,这取决于上下文。为了解决后一个问题,这个提案的一个变体是使用双感叹号操作符(string value!!)。

新属性

另一个选项是增加编译器可以识别的新属性,而不是新语法。


void Insert([NotNull] string value)
复制代码


就 C#而言,影响编译代码的属性并不是什么新东西,所以这可以与现有的模式保持一致。如果我们以前有声明性参数验证,它也会是这样的。


反对这一选项的理由是:


  • 与正在考虑的其他选项相比,它非常啰嗦;

  • 声明参数不可为空是多余的。

编译标识

下一个要考虑的选项是全局编译器标识。当该标识启用时,将检查所有非空参数。


这个选项的好处是你不需要考虑它。一旦启用,检查就会自动添加,这样就不会忘记,也不需要学习特殊的语法。


对此,第一个反对意见是,这可能存在性能方面的考虑。该选项的支持者认为,性能成本微不足道,该特性可以选择性地仅应用于公共方法,但可以对任何方法调用执行空值检查。


反对此特性的另一个理由是,开发人员可能希望抛出不同的异常。与此相反的观点是,除了 ArgumentNullException 之外,他们不应该抛出任何东西。此外,编译器指令可以在需要特殊处理时仅针对一个文件或方法禁用该特性。


最后一个观点最有说服力。这将是编译器标识第二次改变代码的语义。诸如“nullable”之类的编译器标识实际上并不会改变代码的行为方式,它只是一个编译时特性。


这个规则有个例外,就是’checked’编译器标识,它会改变整数溢出的行为。在 C#语言设计人员中,这被认为是一个错误,因为如果不知道编译器级如何设置标识,你就无法判断给定代码段的操作方式。


反对的观点并没有反驳这一点,但是,保持这项更改是使可空引用类型特性接近完成的必要步骤。对此,一些人坚持认为,NRT 从来就不是一个完备的解决方案,为了向后兼容,它不应该影响运行时行为。

外部 AOP 和 IL 织入

术语“IL 织入(IL weaving)”指的是在编译器完成后修改程序集的后处理步骤。这用于面向方面的编程工具,如PostSharp和已取消的Code Contracts项目。


争论中提到了具体的工具Fody NullGuardFody是遵循 MIT 许可协议的 IL 织入器,以Mono.Cecil为基础构建。


反对 IL 织入的理由是它需要第三方工具,不能很好地与 IDE 中运行的静态分析工具协同,会破坏 Edit-and-Continue,降低构建速度。

内部 AOP 或宏系统

有一些关于某种内部 AOP 或宏指令的讨论。这将允许开发人员扩展语言本身,而不是等待 C#的增强。


这次这个选项并没有得到太多的支持。内部 AOP 或宏系统会造成整个工具链的重大变化。此外,它可能会让开发人员创建自己的 C#方言,造成语言割裂。

什么也不做

最后一个选项是什么也不做。最有力的论据是,这仅仅是一个“生活质量”特性,并没有为开发者提供任何新的东西。虽然减少样板文件这点值得赞赏,但它们的负面影响超过了其所带来的好处。


而且,在任何给定的函数中,只需要少量代码来执行空检查。


反驳的观点是,这是 C#中最常见的样板代码示例之一,在示例和生产代码中经常缺失。对此,这一选项的支持者给出的回复是,静态分析工具将检测出大部分(尽管不是全部)空值检查的情况。启用 NRT 后,静态分析检查可以变得更加准确。


原文链接:


C# Futures: Simplified Parameter Null Validation


2020-01-27 09:305517

评论

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

使用 iTerm2 打造美观高效的 Mac 终端

郭旭东

Mac 终端 iterm2

Arthas 定位 Dubbo 手动注册 Eureka 异常

阿里巴巴云原生

阿里云 云原生 dubbo 工具 征文大赛

面试官:不会真有人不知道什么是线程池吧?

Java鱼仔

Java 线程池 并发

Ubuntu 使用 Iptables 做网络转发

wong

iptables Ubuntu20.04

数仓缓慢变化维深层讲解

大数据老哥

大数据 数据仓库 数仓

大数据分析决策平台建设方案,警务情报研判系统搭建

t13823115967

Spring 源码学习 13:initMessageSource

程序员小航

spring 源码 源码解析

mysql binlog轻量同步工具binlog portal

dothetrick

Java MySQL springboot Binlog spring Boot Starter

区块链挖矿系统开发功能方案

影像恋上智能:麒麟9000中的高甜CP创新

脑极体

《数据挖掘:实用的机器学习工具和技术,第4版》PDF版免费下载

计算机与AI

数据挖掘 机器学习 数据科学

数字银行成长性和盈利能力可期

CECBC

数字化转型

Android开发经验谈:2021最新Android常用开源库总结,成功收获美团,小米安卓offer

欢喜学安卓

android 程序员 面试 移动开发

涨知识!一个三非渣本的Android校招秋招之路,赶紧收藏!

欢喜学安卓

android 程序员 面试 移动开发

程序员如何解决中年危机?资深Android开发带你入门Framework,醍醐灌顶!

欢喜学安卓

android 程序员 面试 移动开发

大作业1

蓝黑

免费下载来自阿里巴巴 双11 的《云原生大规模应用落地指南》

阿里巴巴云原生

阿里巴巴 阿里云 开发者 云原生 k8s

甲方日常 79

句子

工作 随笔杂谈 日常

ChaosBlade 在工商银行混沌工程体系中的应用实践

阿里巴巴云原生

云计算 高可用 开发者 云原生 实践

如何通过 Serverless 轻松识别验证码?

阿里巴巴云原生

人工智能 阿里云 Serverless 云原生 数据采集

平安社区平台解决方案,智慧社区综合服务平台搭建

t13823115967

智慧社区管理平台开发

阿里巴巴云原生的 2020,注定不凡的一年

阿里巴巴云原生

阿里云 容器 开发者 云原生 年终总结

稻盛和夫《干法》| 教你做快乐的打工人

小匚

读书笔记 程序员 个人成长

RocketMQ消息模型

废材姑娘

Java RocketMQ

2021 第一份唠嗑

大头虾

数字化浪潮下 哪些银行业务或“生变”

CECBC

金融科技

Pulsar 2.7.0 新增特性概览:事务支持、Topic 级别策略配置等

Apache Pulsar

大数据 开源 pulsar Apache Pulsar 消息中间件

移动设备管理平台的搭建(基于STF/ATXServer2)

行者AI

人工智能

SourceTree 如何连接 GitLab

TroyLiu

git gitlab SSH sourcetree

【薪火计划】07 - 与领导沟通的方法

dstweihao

管理

“区块链+有机蔬菜”农产品溯源项目落地

CECBC

农业发展 农业

C#的未来:简化参数空值验证_语言 & 开发_Jonathan Allen_InfoQ精选文章