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 NullGuard 。 Fody 是遵循 MIT 许可协议的 IL 织入器,以 Mono.Cecil 为基础构建。

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

内部 AOP 或宏系统

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

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

什么也不做

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/312118.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android一键截图代码,偷偷告诉你ADB命令葵花宝典【一键截图和录屏】

先导预告作为一名测试工程师,每天可能都会面临从不同的设备导出截图或视频的工作,有些可能是bug截图或bug回放视频,有些截图可能是提供给PM或UI验收等等。 常规操作是iOS设备可以借助于iTools等工具导出;而安卓设备可能需要从设备…

10进制转换成其他进制-短除法

将10进制下的n转换成b进制下的数。 代码如下: char get(int x) {if (x<9) return x0;return x-10A; }string base(int n,int b) {string num;while(n) num get(n%b),n/b;reverse(num.begin(),num.end());return num; }例题&#xff1a; 回文数是指数字从前往后读和从后往…

【C# 调用 Go 语言】0x1 Hello Golang

C# 和 Golang 都不是世界上最好的语言。在不同的业务场景下&#xff0c;C# 和 Golang 各有所长。如果要编写一个网络程序&#xff0c;显然 Golang 更擅长&#xff0c;而如果要编写一个桌面 GUI 程序&#xff0c;那么 C# 简直不要太爽。我们完全可以将两者用在同一个项目中&…

android仿支付宝弹窗,【转】MUI自定义底部弹窗自带遮罩层仿支付宝支付弹窗

[Asm] 纯文本查看 复制代码html,body{height: 100%;}.fr-tc{/* 控制弹窗高度 */height: 40%;}.fr-div-w{border-radius: 10px 10px 0px 0px;background-color: #FFFFFF;height: 100%;padding: 15px;}.fr-btn{display: block;height: 40px;width: 60%;background-color: #14b5ff…

整数二分

整数二分步骤&#xff1a; 1.找一个区间[L,R],使答案一定在这个区间 2.找一个判断条件&#xff0c;使得该判断条件具有二段性(一般具有单调性)&#xff0c;并且答案一定是该二段性的分界点 3.分析终点M在该判断条件下是否成立&#xff0c;如果成立&#xff0c;考虑答案在哪个区…

解惑小微企业信息化系统上云的顾虑

小微企业到目前阶段&#xff0c;一点信息化系统没上的企业很少了&#xff0c;几乎找不到了。为了满足信息化系统异地办公的外网访问需要&#xff0c;在综合考虑硬件成本和运维成本&#xff0c;初期上云☁应该是最经济实惠的方案。信息化和数字化经济发展不仅给商业模式带来变革…

android 运行在ui县城,Android基础:在UI线程中运行代码

Android基础&#xff1a;在UI线程中运行代码从在UI线程中运行代码的角度来看&#xff0c;在以下方面有什么区别&#xff1a;MainActivity.this.runOnUiThread(new Runnable() {public void run() {Log.d("UI thread", "I am the UI thread");}});或MainAct…

区间合并

区间合并算法&#xff1a; 1.将所有区间按左端点从小到大排序 2.从左到右遍历每个区间 例题&#xff1a; 某校大门外长度为L的马路上有一排树&#xff0c;每两棵相邻的树之间的间隔都是1米。 我们可以把马路看成一个数轴&#xff0c;马路的一端在数轴0的位置&#xff0c;另一端…

云原生时代, 选择.NET Core

在容器、Kubernetes、DevOps&#xff0c;以及微服务等技术的推动下&#xff0c;2020年云原生势不可挡。 .NET Core 也非常契合 云原生对应用运行时的不同需求&#xff0c;.NET Core和kubernetes 同年诞生发展&#xff0c; 2018年kubernetes 已经奠定了在容器编排领域的王者地位…

pm1 android,Android Sensor SDK

Android Sensor SDKStep By Step1.新建工程Android Studio配置将sensoro-sensor-kit.jar包放入道libs文件夹下,然后在当前工程下的build.gradle文件配置项中的dependencies新增内容,&#xff0c;如下compile files(libs/sensoro-sensor-kit.jar)Eclipse配置将sensoro-sensor-ki…

哈希表应用举例

例题&#xff1a; 伊娃喜欢从整个宇宙中收集硬币。 有一天&#xff0c;她去了一家宇宙购物中心购物&#xff0c;结账时可以使用各种硬币付款。 但是&#xff0c;有一个特殊的付款要求&#xff1a;每张帐单&#xff0c;她只能使用恰好两个硬币来准确的支付消费金额。 给定她拥有…

WebApi管理和性能测试工具WebApiBenchmarks

说到WebApi管理和测试工具其实已经非常多的了&#xff0c;Postman、Swagger等在管理和维护上都非常出色&#xff1b;在性能测试方面也有不少的工具如:wrk,bombardier,http_load和ab等等。不过这些工具都具有单一性&#xff0c;管理和维护好的在性能测试上比较低效&#xff0c;对…

android中的shape资源,Android Drawable资源讲解之shape篇

运用好Android的drawable资源&#xff0c;在开发中就可以减少图片的使用量&#xff0c;这样既缩小了app的体积&#xff0c;也省去了设计图片的时间&#xff0c;而且也容易适配不同的屏幕尺寸。今天首先来讲讲shape资源的使用。1. Shape的属性介绍shape共支持四种形状&#xff0…

C++unique函数应用举例

明明想在学校中请一些同学一起做一项问卷调查。 为了实验的客观性&#xff0c;他先用计算机生成了N个1到1000之间的随机整数&#xff0c;对于其中重复的数字&#xff0c;只保留一个&#xff0c;把其余相同的数去掉&#xff0c;不同的数对应着不同的学生的学号。 然后再把这些数…

C# WPF 一个设计界面

微信公众号&#xff1a;Dotnet9&#xff0c;网站&#xff1a;Dotnet9&#xff0c;问题或建议&#xff1a;请网站留言&#xff0c; 如果对您有所帮助&#xff1a;欢迎赞赏。C# WPF 一个设计界面今天正月初三&#xff0c;大家在家呆着挺好&#xff0c;不要忘了自我充电。武汉人民…

android中shape的属性,android中shape的属性

solid&#xff1a;实心&#xff0c;就是填充的意思android:color指定填充的颜色gradient&#xff1a;渐变android:startColor和android:endColor分别为起始和结束颜色&#xff0c;ndroid:angle是渐变角度&#xff0c;必须为45的整数倍。另外渐变默认的模式为android:type”line…

C++to_string应用举例

给定一个非负整数 N&#xff0c;你的任务是计算 N 的所有数字的总和&#xff0c;并以英语输出总和的每个数字。 输入格式 共一行&#xff0c;包含一个整数 N。 输出格式 共一行&#xff0c;用英语输出总和的每个数字&#xff0c;单词之间用空格隔开。 代码如下&#xff1a; …

合集| 21 篇技术文章,带你从零入门 K8s

由阿里云与 CNCF 共同开发的《CNCF x Alibaba 云原生技术公开课》&#xff08;视频课程&#xff09;第一期已更新完毕。为了让大家有更好的学习体验&#xff0c;我们把视频课程转为图文&#xff0c;并请讲师重新编辑成文章&#xff0c;在公众号以“从零入门 K8s” 为系列进行每…

C++string容器应用举例

给定一个整数&#xff0c;请将该数各个位上数字反转得到一个新数。 新数也应满足整数的常见形式&#xff0c;即除非给定的原数为零&#xff0c;否则反转后得到的新数的最高位数字不应为零。 输入格式 输入共1行&#xff0c;1个整数N。 输出格式 输出共1行&#xff0c;1个整数…

家居灯光控制系统设计 android,基于Android的室内照明控制系统设计与实现

摘要&#xff1a;传统的室内照明系统存在控制不方便、布线困难、智能化程度不高等问题,而随着Android智能手机不断发展,已经可以实现多种控制功能。结合WiFi无线通信技术低功耗、高传输速率、组网方便等特点,适合智能化的室内照明控制系统。基于此提出一种以Android手机为平台,…