将结构值分配给此关键字

Posted

技术标签:

【中文标题】将结构值分配给此关键字【英文标题】:Assignment of a struct value to this keyword 【发布时间】:2011-07-30 14:13:59 【问题描述】:

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

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

public CancellationToken( bool canceled )

    this = new CancellationToken();
    if ( canceled )
    
        this.m_source = CancellationTokenSource.InternalGetStaticSource( canceled );
    

this关键字赋值所在的行是什么意思?

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

【问题讨论】:

【参考方案1】:

这是 C# 的一个鲜为人知的特性 - 这允许结构覆盖自己的数据。

就实际应用而言,您不会发现它有很多用途..

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”时——你得到的是一个存在于堆栈上的指针,你实际上并没有得到对象本身。指针隐式地取消引用堆上的对象,这抽象了间接。现在,如果可以在类中分配给this,并且您会说类似this = new MyReferenceType() 的话,那么您将更改指针以指向当前范围 中的不同堆对象 -您不会更改堆中的原始对象本身,也不会导致任何其他引用/指针引用新的堆对象。很有可能,一旦您的变异指针超出范围 - 您创建的新堆对象就会受到垃圾回收的影响。

当您在值类型上调用“this”时 - 您得到的是实际对象,而不是引用或指针。没有间接性,因此您可以随意覆盖此内存位置的原始位(这正是默认构造函数所做的)。

【讨论】:

【参考方案2】:

只是猜测:

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

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

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

再说一次,这只是我的想法,我非常希望有人能够证明或放弃(当然要给出解释)。

【讨论】:

以上是关于将结构值分配给此关键字的主要内容,如果未能解决你的问题,请参考以下文章

数据结构散列表

对 *.svc 的 HTTP 请求已超过分配的超时。分配给此操作的时间可能是较长超时的一部分。

java 数组操作

c语言中啥是类(class),啥是结构。两者有啥区别?详细点。书上不太清楚。。谢谢

static 和 final 关键字 对实例变量赋初始值的影响

数据结构C++用链表实现一个箱子排序附源代码详解