C# C语言中的自赋值#

C# C语言中的自赋值#,c#,assignment-operator,C#,Assignment Operator,我正在浏览我不久前编写的一些代码,意识到我对C#中的赋值运算符做了一个假设。下面是有问题的代码行(它按预期工作): 但我更愿意理解自赋值的实际情况。赋值将引用复制到对象,而不是对象内容。没有可自定义的代码作为保存对象引用的变量赋值的一部分运行。结构也是如此 C++赋值是可定制的,在C语言中不是. 可以安全地将同一对象引用指定给已包含该对象的变量: object someRef = new object(); someRef = someRef; //always does nothing 这

我正在浏览我不久前编写的一些代码,意识到我对C#中的赋值运算符做了一个假设。下面是有问题的代码行(它按预期工作):


但我更愿意理解自赋值的实际情况。

赋值将引用复制到对象,而不是对象内容。没有可自定义的代码作为保存对象引用的变量赋值的一部分运行。结构也是如此

<> C++赋值是可定制的,在C语言中不是.

可以安全地将同一对象引用指定给已包含该对象的变量:

object someRef = new object();
someRef = someRef; //always does nothing
这与分配任何其他值一样安全:

int someVal = 123;
someVal = someVal; //always does nothing
请注意,不存在克隆/复制对象的通用方法。任何依赖这种机制的解释都是错误的

自分配是安全的,因为它转换为以下近似IL指令:

ldloc someRef
stloc someRef

这有明确定义的语义。它首先将
someRef
加载到堆栈上,然后将堆栈上的任何内容存储到
someRef

尝试优化字段上的自赋值(非正常局部变量)可能会对多线程代码产生一些非平凡的影响。不确定CLR内存模型是否允许优化。C是不是C++。在重载赋值运算符中防止自赋值的整个思想毫无意义。当一个包含对象的变量被赋值时,对象不能发生变化,它要么是一个指向其他地方的对象引用,要么是一个值类型的内容被该类型的另一个实例的内容覆盖,就像被该类型的另一个实例的内容覆盖一样。@millimose我意识到了这一点。我不是要防止自我赋值,你甚至不能在C#中重载赋值操作符。我是说我假设在幕后有一个类似的构造,并希望对实际发生的事情进行一些澄清。@prettycooldevguy在幕后
pointsChecked
变量的存储桶将保持其原始值,如果原始值为
0
,则为
列表的对象句柄。原始值是否自赋值并不重要,因为它只是一个指针或不透明的对象引用。不管发生了什么都不重要——如果这对您来说不是完全透明的,那么只要在C中不存在自赋值的概念,这将是C实现中的一个bug。有趣的是,您能否更详细地说明当您在结构上重载
操作符=
时会发生什么,以及它可能(或不能)发生什么是否影响?不能重载赋值运算符。既不适用于引用类型,也不适用于结构。结构复制是一个指定的IL指令,它指示运行时执行按位复制。啊,我明白了。显示我尝试重载运算符的频率。+1。注意“C++赋值是可定制的”是不完整的- C++的赋值对于指针不能重载(指针指向对象表示什么<代码> SOMEVAR <代码> >代码>本质上是……谢谢,我想我只是在想它。很高兴知道这一点,我还没有看到其他解释,所以希望这对其他人也有帮助!
int someVal = 123;
someVal = someVal; //always does nothing
ldloc someRef
stloc someRef