Why is the Elvis (?.) Statement not working with asynchronous wait?

Suppose you have the following code (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 doesn't the Elvis statement work with asynchronous wait? Did I miss something?

+4
source share
2 answers

The translation awaitis that, firstly, it GetAwaiter()is called on the expected object (in your case a Task). He then does some other complicated things, but here they are not relevant:

await MyClass?.Job();

Compiles:

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

Since it Task.GetAwaiter()is an instance method, and you call it with null Task, you get NullReferenceException.


, await a 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
+9

:

async void Main()
{
    var thing = new MethodClass();
    await thing.Job();
}
public class MethodClass
{
    public Func<Task> Job = null;
}

, null - , NullReferenceException

+3

Source: https://habr.com/ru/post/1659907/


All Articles