为什么Elvis(.)运算符不能与async-await一起工作
本文关键字:async-await 一起 工作 不能 运算符 Elvis 为什么 | 更新日期: 2023-09-27 18:16:21
让我们有一个这样的代码(App.xaml.xs的片段):
public class MethodClass
{
public async Task Job()
{
Debug.WriteLine("Doing some sob");
await Task.Delay(1);
}
}
public MethodClass MyClass = null;
protected async override void OnLaunched(LaunchActivatedEventArgs e)
{
await MyClass?.Job(); // here goes NullreferenceException
MyClass?.Job(); // works fine - does nothing
为什么猫王操作符不能使用async-await?我错过什么了吗?
翻译await
的方式是,首先在等待的对象(在您的示例中是Task
)上调用GetAwaiter()
。然后它做一些其他复杂的事情,但这些与这里无关:
await MyClass?.Job();
编译:
var awaiter = MyClass?.Job().GetAwaiter();
// more code
因为Task.GetAwaiter()
是一个实例方法,你用null
Task
调用它,你得到一个NullReferenceException
。
作为一个好奇心,await
是可以等待的null
,只要它的GetAwaiter()
是一个接受null
的扩展方法:
public class NullAwaitable { }
public static class Extensions
{
public static TaskAwaiter GetAwaiter(this NullAwaitable _)
=> Task.CompletedTask.GetAwaiter();
}
public class MethodClass
{
public NullAwaitable Job() => new NullAwaitable();
}
MethodClass MyClass = null;
await MyClass?.Job(); // works fine