.NET 6新特性试用 | ArgumentNullException卫语句

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了.NET 6新特性试用 | ArgumentNullException卫语句相关的知识,希望对你有一定的参考价值。

前言

在前面的文章中(《可空引用类型》),我们介绍过编译器会帮我们检查空引用,但是仅仅是警告。最好的方式还是在运行时用卫语句进行检查:

private void Test(WeatherForecast weatherForecast)

    if (weatherForecast == null)
     
        throw new ArgumentNullException(nameof(weatherForecast));
    

在.NET 6中,在ArgumentNullException类中添加了一个名为ThrowIfNull的新静态方法,它允许我们快速检查和抛出 ArgumentNullExceptions:

有意思的是,异常信息自动带出了参数名称,这样可以有效避免使用nameof用错参数。

那这是怎么做到的呢?

原理探究

查看ThrowIfNull的定义,可以看到还有一个默认参数,使用了CallerArgumentExpression属性声明:

public static void ThrowIfNull([NotNull] object? argument, [CallerArgumentExpression("argument")] string? paramName = null)

在编译时,编译器会把上面的代码编译成如下形式,传入了参数名:

ArgumentNullException.ThrowIfNull(weatherForecast, "weatherForecast");

原理利用

很可惜,.NET 6没有提供更多类似ThrowIfNull的帮助方法,但是我们可以利用CallerArgumentExpression实现自己的帮助类来简化卫语句。

比如:

public class ArgumentExceptionHelper 
    public static void ThrowIfNullOrEmpty(string? argument, [CallerArgumentExpression("argument")] string? paramName = null)
    
        if(string.IsNullOrEmpty( argument))
            throw new ArgumentNullException(paramName);
    

    public static void ThrowIfOutOfRange(bool argument, [CallerArgumentExpression("argument")] string? paramName = null)
    
        if (argument)
            throw new ArgumentOutOfRangeException(paramName);
    


//使用
ArgumentExceptionHelper.ThrowIfNullOrEmpty(name);

ArgumentExceptionHelper.ThrowIfOutOfRange(age <= 0);

最为奇妙的是,CallerArgumentExpression的功能是表示一个参数将传递给另一个参数的表达式作为字符串捕获。,错误提示的不是参数名称,而是实际传入的表达式,因此更清晰。

例如下面的错误提示Age<=0:

结论

在.NET 6之前,.NET中已有三个[Caller*]属性可用:

  • [CallerMemberName]

  • [CallerFilePath]

  • [CallerLineNumber]

详细介绍请参看:https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callermembernameattribute

利用这些属性,可以让编译器“神奇地”填充它们,帮助我们轻松获取调用者信息。

如果你觉得这篇文章对你有所启发,请帮忙点个或者在看

以上是关于.NET 6新特性试用 | ArgumentNullException卫语句的主要内容,如果未能解决你的问题,请参考以下文章

.NET 6新特性试用 | PeriodicTimer

.NET 6新特性试用 | 可空引用类型

.NET 6新特性试用 | TryGetNonEnumeratedCount

.NET 6新特性试用 | PriorityQueue

.NET 6新特性试用 | 无需配置开发人员异常页

.NET 6新特性试用 | 异步流