为此关键字分配结构值

Res*_*ing 7 c# constructor struct this variable-assignment

我最近正在研究CancellationToken结构的内部结构并发现了一些奇怪的构造(更准确地说,是为this关键字赋值).

其构造函数之一的代码如下:

public CancellationToken( bool canceled )
{
    this = new CancellationToken();
    if ( canceled )
    {
        this.m_source = CancellationTokenSource.InternalGetStaticSource( canceled );
    }
}
Run Code Online (Sandbox Code Playgroud)

this关键字赋值的行的含义是什么?

请注意,this类不能为关键字赋值- 出现错误Cannot assign to '<this>' because it is read-only.

Mat*_*vey 7

这是C#的一个鲜为人知的特性 - 这允许结构覆盖自己的数据.我不确定这是否仅适用于blittable值类型(我猜不是).

就实际应用而言,你不会找到很多用途.

struct MyStruct
{
    int a = 1;
    int b = 2;
    int c = 3;

    public void Mutate()
    {
        a = 10;
        b = 20;
        c = 30;
    }

    public void Reset()
    {
        a = 1;
        b = 2;
        c = 3;
    }

    public void Reset2()
    {
        this = new MyStruct();
    }

    // The two Reset methods are equivilent...
}
Run Code Online (Sandbox Code Playgroud)

更多地考虑它,当你处理价值类型与参考类型时,"这"意味着什么是根本区别.

当你在引用类型上调用"this"时 - 你得到的是一个存在于堆栈中的指针,你实际上并没有得到对象本身.指针隐式地取消引用回到堆上的对象,该对象抽象出间接.现在如果你说像this = new MyReferenceType(),你已经将指针更改为指向当前作用域中的不同堆对象- 你没有在堆中更改原始对象本身,也没有更改任何其他引用/指针现在引用新的堆对象.很可能一旦你的变异指针超出范围 - 你创建的新堆对象将受到垃圾收集.

当您在值类型上调用"this"时 - 您将获得实际对象,而不是引用或指针.没有间接,所以你可以自由地覆盖这个内存位置的原始位(这正是默认构造函数所做的).