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

前言

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

private void Test(WeatherForecast weatherForecast)
{
    if (weatherForecast == null)
    { 
        throw new ArgumentNullException(nameof(weatherForecast));
    }
}

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

bd0b9e7da6a9d33c6b16376b26ae9eb0.png

有意思的是,异常信息自动带出了参数名称,这样可以有效避免使用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:

7a6d519d4fe775f1a4eeba040c8e279c.png

结论

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

  • [CallerMemberName]

  • [CallerFilePath]

  • [CallerLineNumber]

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值