空条件运算符和等待的 C# 错误

C# Error with null-conditional operator and await

我在 C# 中使用新的 null 条件运算符时遇到了一个有趣的 System.NullReferenceException。如果 "MyObject" 为空,以下代码会给我一个 NullReferenceException:

await this.MyObject?.MyMethod()

如果 "MyObject" 为 null,我本以为不会调用 "MyMethod",或者我是否误解了 null 条件运算符的目的?

您可以添加 ?? 运算符,因此如果 ?. returns 空任务改用 CompletedTask。

await (this.MyObject?.MyMethod() ?? Task.CompletedTask)

I would've expected that the call to "MyMethod" would simply not be made if "MyObject" is null.

没错。 ?. 运算符 returns 空任务而不是调用 MyMethod。空引用异常是因为您不能等待空任务。必须初始化任务。

围绕 await 中 null 条件的尴尬进行了很多讨论。您可以在 C# 提案 Champion "Null-conditional await" #35 中看到其中的一些内容。虽然接受的答案有效,但我相信两种扩展方法可以更好地封装行为:

public static Task ForAwait(this Task task)
{
    return task ?? Task.CompletedTask;
}

public static Task<T> ForAwait<T>(this Task<T> task, T defaultValue = default)
{
    return task ?? Task.FromResult(defaultValue);
}

您可以将它们用作:await (this.MyObject?.MyMethod()).ForAwait()注意额外的括号!如果默认情况下 default(T) 不是您想要的 return,您甚至可以指定自己的默认值。我已经看到其他人做了类似的事情,并且还添加了一个额外的参数,该参数将 ConfigureAwait 放入方法中。

我很想以某种方式摆脱丑陋的括号,但语言不允许(还没有?)。