编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

C# 11加入检查参数是否为空语法糖

wxchong 2024-06-14 13:10:56 开源技术 73 ℃ 0 评论

起因

在C# 11中,加入了新的语法糖,在C#加入越来越多的语法,当编程语言加入太多的语法,会导致阅读代码时有些晦涩,不易读,刚开始不知道这个语法是要做什么,这个时候就要去官方文档,看看这个语法的功能是要做什么.

最早看到这个检查参数是否为空的语法是从这几个issue:

  1. Initial roll out of !! (#64720)
  2. Second round of changing null checks to !! (#65108)
  3. Add/use ArgumentException.ThrowIfNullOrEmpty (#64357)

目前新语法在检查参数为空,只能用在方法内的参数和构造方法的参数,对于方法内的参数使用ref和out修饰都是不可以的.

1. 在普通方法,使用新语法校验参数是否为空

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#语言版本,会有提示信息(这里使用的是.Net 7 Preview1,VS版本为2022 17.1.0)

在VS 2022正式版,没有版本在界面管理器中修改C#语言版本,这里修改项目工程文件(*.csproj)

<PropertyGroup>
	<OutputType>Exe</OutputType>
	<!--指定.Net版本-->
	<TargetFramework>net7.0</TargetFramework>
	<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
	<!--指定c#语言版本为与蓝本(preview)-->
	<LangVersion>preview</LangVersion>
</PropertyGroup>

2.在构造方法中检查参数是否为空

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;
    }
}

3.使用反编译工具 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
		<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:


个人能力有限,如果您发现有什么不对,请私信我

如果您觉得对您有用的话,可以点个赞或者加个关注,欢迎大家一起进行技术交流

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表