为什么我不能等待对象类型?

时间:2017-07-12 08:50:37

标签: c# async-await

最近我意识到如果我为该类型实现GetAwaiter扩展方法,我实际上可以做任何事情。我知道这完全是胡说八道,但我开始玩这个只是为了好玩:

// a minimal awaiter to make the compiler happy
public class MyAwaiter<T> : INotifyCompletion
{
    public bool IsCompleted { get; } = true

    public T GetResult() => default(T);

    public void OnCompleted(Action continuation) { }
}

所需的扩展方法:

public static class Extensions
{
    // await them all!
    public static MyAwaiter<T> GetAwaiter<T>(this T obj)
    {
        return new MyAwaiter<T>();
    }
}

现在我可以犯这个黑魔法了:

private async Task Magic()
{
    await "haha!";
    await 42;
    // await new object(); // <- this line does not compile
}

等待对象失败:

  

ConfiguredTaskAwaitable<object>不包含IsCompleted

的定义

当我返回ConfiguredTaskAwaitable<object>实例时,我不明白MyAwaiter<T>是如何进入的。但没关系,第二次尝试:

public static MyAwaiter<object> GetAwaiter(this object obj)
{
    return new MyAwaiter<object>();
}

现在没有人等待工作:

  

以下方法或属性之间的调用不明确:Test.Extensions.GetAwaiter(object)Test.Extensions.GetAwaiter(object)

这比前一个更令人困惑。

如果我将签名中的类型更改为stringint,那么我可以分别等待字符串和整数;但是,object不起作用。有人知道在object的情况下背景会发生什么吗?

1 个答案:

答案 0 :(得分:4)

我能看到的唯一问题是缺少分号:

await new object();

您的代码在第二次尝试之前(前三段代码)包括shadowJar { relocate 'junit.framework', 'shadow.junit' } 在我的机器上编译,就像预期的那样。我在VS 2017 Community v15.2(26430.6)中尝试了.NET CORE和.NET framework 4.6控制台应用程序。

再次检查您的代码和编译器版本。