简体   繁体   中英

Why Elvis (?.) operator doesn't work with async-await?

Let's have a code like this (fragment of 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

Why Elvis operator doesn't work with async-await ? Am I missing something?

The way await is translated is that first, GetAwaiter() is called on the awaited object (in your case, a Task ). It then does some other complicated things, but those are not relevant here:

await MyClass?.Job();

Compiles to:

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

Since Task.GetAwaiter() is an instance method and you're calling it with a null Task , you get a NullReferenceException .


As a curiosity, it is possible to await a null awaitable, as long as its GetAwaiter() is an extension method that accepts 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM