C# 为什么任务实现IAsyncResult,但不包含AsyncWaitHandle成员?

C# 为什么任务实现IAsyncResult,但不包含AsyncWaitHandle成员?,c#,oop,interface,task,iasyncresult,C#,Oop,Interface,Task,Iasyncresult,也许这是个愚蠢的问题 任务类的声明方式如下: public class Task : IThreadPoolWorkItem, IAsyncResult, IDisposable IAsyncResult接口声明如下: public interface IAsyncResult { object AsyncState { get; } WaitHandle AsyncWaitHandle { get; } bool CompletedSynchronously { ge

也许这是个愚蠢的问题

任务
类的声明方式如下:

public class Task : IThreadPoolWorkItem, IAsyncResult, IDisposable
IAsyncResult
接口声明如下:

public interface IAsyncResult
{
    object AsyncState { get; }
    WaitHandle AsyncWaitHandle { get; }
    bool CompletedSynchronously { get; }
    bool IsCompleted { get; }
}
但是成员
AsyncWaitHandle
不存在于
Task
类或实例中

此代码:

System.Threading.Tasks.Task t = new System.Threading.Tasks.Task(() => { }); 
t.AsyncWaitHandle.ToString(); 
引发此编译错误:

错误1“System.Threading.Tasks.Task”不包含定义 对于“AsyncWaitHandle”和无扩展方法“AsyncWaitHandle” 无法接受类型为“System.Threading.Tasks.Task”的第一个参数 被找到(是否缺少using指令或程序集引用?)

然而,这不仅包括:

System.IAsyncResult t = new System.Threading.Tasks.Task(() => { }); 
t.AsyncWaitHandle.ToString(); 
但也可以,因为成员存在。这是什么魔法

这是一个编译器技巧,还是以另一种方式隐藏


干杯。

任务
显式实现了
IAsyncResult
,因此您必须先施放:

System.Threading.Tasks.Task t = new System.Threading.Tasks.Task(() => { }); 
((IAsyncResult)t).AsyncWaitHandle.ToString()
显式实现的定义如下:

public class Task : IAsyncResult
{
    WaitHandle IAsyncResult.AsyncWaitHandle
    {
        get { ... }
    }
}

msdn文档对其进行了很好的总结

类成员IControl.Paint仅通过IControl可用 接口和ISurface。只能通过ISurface进行绘制。二者都 方法实现是独立的,两者都不直接可用 在课堂上


这里的要点是显式接口实现是私有的,并且与编译器magic绑定。

这就是为什么我没有通过其元数据在Visual Studio中看到它,因为显式实现不是公共的。我没有想到这一点。谢谢。这看起来是件可怕的事。这不是LSP的一个转折点吗?@vortola根据您对接口的考虑,这是一个直接违反。但是,接口不是抽象类型。它们只是说明您可以安全转换到接口“类型”的契约。我也不是一个粉丝,但这是一贯的。@vtortola我更担心的是你会这样做-这是一个具体的违反SRP的行为。
interface IControl
{
    void Paint();
}
interface ISurface
{
    void Paint();
}
class SampleClass : IControl, ISurface
{
    void IControl.Paint()
    {
        System.Console.WriteLine("IControl.Paint");
    }
    void ISurface.Paint()
    {
        System.Console.WriteLine("ISurface.Paint");
    }
}