static async Task MainAsync()
    {
        // IFuture awaited
        await WaitAsync();

        // IFuture<T> awaited
        Console.WriteLine(await WaitAndReturnAsync());

        // IFuture<Parent> (that actually implements IFuture<Child>) awaited
        var childFuture = CreateChild();
        IFuture <Parent> parentFuture = childFuture; // Implicit conversion from IFuture<Child> to IFuture<Parent>
        var result = await parentFuture;

        Console.WriteLine(result.GetType().Name);

        // IFuture configured and awaited
        await WaitAsync().ConfigureAwait(false);

        // IFuture<T> configured and awaited
        Console.WriteLine(await WaitAndReturnAsync().ConfigureAwait(false));

        // IFuture<Parent> (that actually implements IFuture<Child>) configured and awaited
        var childFuture2 = CreateChild();
        IFuture <Parent> parentFuture2 = childFuture2; // Implicit conversion from IFuture<Child> to IFuture<Parent>
        var result2 = await parentFuture2.ConfigureAwait(false);

        Console.WriteLine(result2.GetType().Name);
    }