如果对象为 null,则引发异常

本文关键字:异常 对象 null 如果 | 更新日期: 2023-09-27 18:35:03

我最近发现:

if (Foo() != null)
    { mymethod(); }

可以改写为:

Foo?.mymethod()

以下内容可以以类似的方式重写吗?

if (Foo == null)
    { throw new Exception() }

如果对象为 null,则引发异常

是的,从 C# 7 开始,您可以使用抛出表达式

var firstName = name ?? throw new ArgumentNullException("Mandatory parameter", nameof(name));

从 .NET 6 开始,可以使用ArgumentNullException.ThrowIfNull()静态方法:

void HelloWorld(string argumentOne)
{
    ArgumentNullException.ThrowIfNull(argumentOne);
    Console.WriteLine($"Hello {argumentOne}");
}

C# 6 中没有类似的时尚语法。

但是,如果需要,可以使用扩展方法简化空检查...

 public static void ThrowIfNull(this object obj)
    {
       if (obj == null)
            throw new Exception();
    }

用法

foo.ThrowIfNull();

或者改进它以显示空对象名称。

 public static void ThrowIfNull(this object obj, string objName)
 {
    if (obj == null)
         throw new Exception(string.Format("{0} is null.", objName));
 }
foo.ThrowIfNull("foo");
我不知道

你为什么会..

public Exception GetException(object instance)
{
    return (instance == null) ? new ArgumentNullException() : new ArgumentException();
}
public void Main()
{
    object something = null;
    throw GetException(something);
}
如果为 null,

则为 null;如果不是,则为点

使用 null 条件的代码可以通过在阅读时对自己说出该语句来轻松理解。因此,例如在您的示例中,如果 foo 为 null,那么它将返回 null。 如果它不是空的,那么它会"点",然后抛出一个我认为不是你想要的异常。

如果您正在寻找一种处理空检查的速记方法,我会推荐 Jon Skeet 的答案以及他关于该主题的相关博客文章。

黛博拉·仓田(Deborah Kurata(在我也推荐的Pluralsight课程中引用了这句话。

使用启用了Nullable指令的 C#10,我经常需要将类型 T? 的值转换为 T 。例如,我在表示配置部分的类中有一个属性string? ServerUrl(它是可为空的,因为它可能无法由用户设置(,我需要将其作为参数传递给采用不可为空string的方法。在许多情况下,处理可为空类型的缺失值是很乏味的。一种可能的解决方案是使用 !(null 宽容(,但在实际null值的情况下,它将只产生 NullReferenceException .或者,如果您希望获得更多信息异常,则可以为经过验证的转化定义扩展方法,一种用于值类型,一种用于引用类型,如下所示:

public static class NullableExtensions
{
    public static T ThrowIfNull<T>(
        this T? input, [CallerArgumentExpression("input")] string? description = null)
        where T : struct =>
        input ?? ThrowMustNotBeNull<T>(description);
    public static T ThrowIfNull<T>(
        this T? input, [CallerArgumentExpression("input")] string? description = null)
        where T : class =>
        input ?? ThrowMustNotBeNull<T>(description);
    private static T ThrowMustNotBeNull<T>(string? description) =>
        throw new InvalidOperationException($"{description} must not be null");
}

这些方法采用可选参数description允许使用 CallerArgumentExpression 属性捕获作为参数传递的表达式。

用法示例:

string? a = null;
a.ThrowIfNull(); // throws exception with message "a must not be null"
int? b = null;
int? c = 5;
(b + c).ThrowIfNull(); // throws exception with message "b + c must not be null"

.NET 小提琴示例

我不建议滥用这种方法,而不是以严格类型的方式正确处理可为空的值。您可以将其视为断言(或禁止警告(值已设置或发生开发人员错误的方式。同时,您还希望获得其他信息,并且不考虑运行时性能影响(相比之下,运算符 ! 没有任何运行时影响(。