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

Rom*_*asz 7 c# windows async-await c#-6.0 uwp

让我们有这样的代码(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
Run Code Online (Sandbox Code Playgroud)

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

svi*_*ick 12

await翻译的方式是,首先,GetAwaiter()在等待的对象上调用(在您的情况下,a Task).然后它做了一些其他复杂的事情,但这些不相关:

await MyClass?.Job();
Run Code Online (Sandbox Code Playgroud)

编译为:

var awaiter = MyClass?.Job().GetAwaiter();
// more code
Run Code Online (Sandbox Code Playgroud)

既然Task.GetAwaiter()是一个实例方法,并且你用a调用它null Task,你得到一个NullReferenceException.


作为好奇心,有可能await一个nullawaitable,只要其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
Run Code Online (Sandbox Code Playgroud)