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); }