如果对象为空则抛出异常

问题描述 投票:0回答:6

我最近发现:

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

可以改写为

Foo?.mymethod()

下面可以用类似的方式重写吗?

if (Foo == null)
{ throw new Exception()}
c# .net visual-studio null operators
6个回答
26
投票

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

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

来源


14
投票

从 .NET 6 开始,您可以使用

ArgumentNullException.ThrowIfNull()
静态方法:

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

9
投票

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");

4
投票

我不知道你为什么会..

public Exception GetException(object instance)
{
    return (instance == null) ? new ArgumentNullException() : new ArgumentException();
}

public void Main()
{
    object something = null;
    throw GetException(something);
}

1
投票

如果为空则为空;如果不是那么点

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

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

Deborah Kurata我也推荐的 Pluralsight 课程 中引用了这句话。


0
投票

在启用

Nullable
指令的情况下使用 C#10 我经常需要将类型
T?
的值转换为
T
。例如,我在表示配置部分的类中有一个属性
string? ServerUrl
(它可以为空,因为它可能无法由用户设置)我需要将它作为参数传递给采用不可为空
string
的方法。在许多此类情况下,处理可为 null 类型的缺失值非常乏味。一种可能的解决方案是使用 !(null-forgiving) 但在实际
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 小提琴示例

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

© www.soinside.com 2019 - 2024. All rights reserved.