Visual Studio 如果对象为空则引发异常

e4yzc0pl  于 2023-04-07  发布在  其他
关注(0)|答案(6)|浏览(221)

我最近发现:

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

可以重写为

Foo?.mymethod()

下面的句子可以用类似的方式改写吗?

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

iaqfqrcu1#

是的,从C#7开始,你可以使用Throw表达式

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

Source

z2acfund

z2acfund2#

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

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

rpppsulh3#

在C# 6中没有类似的时尚语法。
但是,如果你愿意,你可以通过使用扩展方法来简化null检查...

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

sbdsn5lh4#

我不知道你为什么...

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

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

z0qdvdin5#

If null then null; if not then dot
使用null条件的代码可以很容易地理解,只要在阅读它的时候对自己说这句话。例如在你的例子中,如果foo是null,那么它将返回null。如果它不是null,那么它将“点”,然后抛出一个异常,我不相信这是你想要的。
如果您正在寻找一种处理null检查的快捷方式,我推荐Jon Skeet's answer here和他的相关blog post
Deborah Kuratathis Pluralsight course中引用了这句话,我也推荐这句话。

ktecyv1j

ktecyv1j6#

使用C#10并启用Nullable指令时,我经常需要将T?类型的值转换为T。例如,我在类中有一个属性string? ServerUrl,表示配置部分(它是可空的,因为它可能无法由用户设置),我需要将它作为参数传递给接受不可空的string的方法。在许多此类情况下,处理可空类型的缺失值是繁琐的。一种可能的解决方案是使用!(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 Fiddle example
我不建议滥用这种方法,而不是以严格类型的方式正确处理可空值。您可以将其视为Assert(或抑制警告)的方式,即设置了值或发生了开发人员的错误。同时,您还希望获得额外的信息,并且不会考虑运行时性能影响(operator!相比之下,没有任何运行时影响)。

相关问题