11

当我创建一个默认值时CancellationToken,我可以在调试器中看到它CancellationToken有一个CancellationTokenSource与之关联的存储在私有m_source字段中:

不为空

我想知道对于结构来说,default关键字“将根据它们是值类型还是引用类型,将结构的每个成员初始化为零或null”并且CancellationTokenSource是引用类型。

CancellationToken确实有 2 个设置此字段的构造函数,但是它们不相关,因为default(CancellationToken)不调用构造函数并且new CancellationToken()(具有完全相同的行为)不调用构造函数,因为结构不能具有无参数构造函数(尚未)。

4

1 回答 1

15

default(CancellationToken)确实创建了CancellationTokenwhere m_sourceis null。您可以通过使用反射获取该私有字段的值来看到这一点:

Console.WriteLine(typeof (CancellationToken).
    GetField("m_source", BindingFlags.NonPublic | BindingFlags.Instance).
    GetValue(default(CancellationToken)) ?? "null");

输出:

null

您还可以通过仅在调试器中固定相关字段来看到这一点:

无效的

那么,会发生什么?

调试器为了显示 的内容,会CancellationToken一一访问其属性。当内部CancellationTokenSource是属性时,在委托给它的属性之前null创建WaitHandle并设置一个默认值:CancellationTokenSourceWaitHandle

public WaitHandle WaitHandle
{
    get
    {
        if (m_source == null)
        {
             m_source = CancellationTokenSource.InternalGetStaticSource(false);
        }

        return m_source.WaitHandle;
    }
}

总之,default(CancellationToken)创建new CancellationToken一个空结构 where m_sourceisnull但是通过查看调试器中的结构,您正在CancellationTokenSource使用无法取消的默认实例填充该字段。

于 2015-03-30T19:58:26.777 回答