为此关键字指定struct值

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

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

 public CancellationToken( bool canceled ) { this = new CancellationToken(); if ( canceled ) { this.m_source = CancellationTokenSource.InternalGetStaticSource( canceled ); } } 

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

请注意,类不能this关键字赋值 – 错误Cannot assign to '' because it is read-only

这是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... } 

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

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

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

只是一个猜测:

每个类都是一个引用类型,这意味着内存在堆中分配,调用者可以通过指针访问实际数据。 例如:

 Customer c1 = new Customer('CUSTID'); // "Customer" is a reference type Customer c2 = c1; // "c1" and "c2" points to the same memory within the heap 

每个结构都是一个值类型,意味着内存在堆栈中分配,调用者处理实际实例而不是对该实例的引用。 例如:

 Customer c1 = new Customer('CUSTID'); // "Customer" is a value type Customer c2 = c1; // New memory gets allocated for "c2" within the stack 

考虑你的例子:

 this = new Customer(); 

在结构上执行以下操作只需使用零值初始化它:

 mov eax,dword ptr [ebp-3Ch] ; Save pointer to "ebp-3Ch" in EAX register xor edx,edx ; Clear EDX register mov dword ptr [eax],edx ; Write "zero" by address containing in EAX 

我不知道为什么引用类型不可能,但我的猜测是需要遍历整个对象图以完全“重置”它(这可能不是一件容易的事)。 我认为这将在循环引用的情况下变得有价值。

再一次,这只是我的想法,我非常希望有人能够certificate或丢弃(当然有解释)。