C# 11加入检查参数是否为空语法糖
起因
在C# 11中,加入了新的语法糖,在C#加入越来越多的语法,当编程语言加入太多的语法,会导致阅读代码时有些晦涩,不易读,刚开始不知道这个语法是要做什么,这个时候就要去官方文档,看看这个语法的功能是要做什么.最早看到这个检查参数是否为空的语法是从这几个issue:
- Initial roll out of !! (#64720)
- Second round of changing null checks to !! (#65108)
- Add/use ArgumentException.ThrowIfNullOrEmpty (#64357)
目前新语法在检查参数为空,只能用在方法内的参数和构造方法的参数,对于方法内的参数使用ref和out修饰都是不可以的.
在普通方法,使用新语法校验参数是否为空
public bool Test1(string name)
{
if (name == null)
{
throw new ArgumentNullException(nameof(name));
}
//等同于上方 if(name == null) { throw new ArgumentNullException("name");)
//这种方式可以用在检查属性是否为空
ArgumentNullException.ThrowIfNull(nameof(name));
return true;
}
public bool Test2(string name!!) //新语法, 在参数名加!!
{
return true;
}
要在项目工程文件,指定C#语言版本.
<PropertyGroup>
<OutputType>Exe</OutputType>
<!--指定.Net版本-->
<TargetFramework>net7.0</TargetFramework>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<!--指定c#语言版本为与蓝本(preview)-->
<LangVersion>preview</LangVersion>
</PropertyGroup>
在构造方法中检查参数是否为空
public class CheckParameterNull
{
public string Address { get; }
public CheckParameterNull(string address!!) //在构造方法,使用新语法检查参数是否
{
Address = address;
}
public bool Test1(string name)
{
if (name == null)
{
throw new ArgumentNullException(nameof(name));
}
//等同于上方 if(name == null) { throw new ArgumentNullException("name");)
//这种方式可以用在检查属性是否为空
ArgumentNullException.ThrowIfNull(nameof(name));
return true;
}
public bool Test2(string name!!) //新语法, 在参数名加!!
{
return true;
}
}
使用反编译工具 ILSpy 查看编译后的代码:
public class CheckParameterNull
{
public string Address { get; }
public CheckParameterNull(string address)
{
//编译器在编译时,会在程序集生成一个隐藏类PrivateImplementationDetails
<PrivateImplementationDetails>.ThrowIfNull(address, "address");
base..ctor();
Address = address;
}
public bool Test1(string name)
{
if (name == null)
{
throw new ArgumentNullException("name");
}
ArgumentNullException.ThrowIfNull("name", "nameof(name)");
return true;
}
public bool Test2(string name)
{
<PrivateImplementationDetails>.ThrowIfNull(name, "name");
return true;
}
}
编译器在编译时,会生成一个隐藏类PrivateImplementationDetails
[CompilerGenerated]
internal sealed class <PrivateImplementationDetails>
{
internal static void Throw(string paramName)
{
//最终还是调用创建一个ArgumentNullException
throw new ArgumentNullException(paramName);
}
internal static void ThrowIfNull(object argument, string paramName)
{
if (argument == null)
{
Throw(paramName);
}
}
}
对于这个新的语法糖,我是支持的,因为这个语法糖是可以提高一些生产力(这一点不是很多),但可以减少代码量,让项目的代码量不至于越来越膨胀.
这个看#65108这个issue:
通过这个issue,这个语法是可以减少代码量的.
秋风
2022-02-18