C# · 12月 24, 2021

c# – 为什么Elvis(?.)运算符不能与async-await一起使用?

让我们有这样的代码(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

为什么Elvis运算符不能与async-await一起使用?我错过了什么吗?

解决方法 等待转换的方式是,首先,在等待的对象上调用GetAwaiter()(在您的情况下,是一个Task).然后它做了一些其他复杂的事情,但这些不相关: await MyClass?.Job();

编译为:

var awaiter = MyClass?.Job().GetAwaiter();// more code

由于Task.GetAwaiter()是一个实例方法,并且您使用null Task调用它,因此会出现NullReferenceException.

作为好奇心,可以等待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