gpt4 book ai didi

c# - C#中的自赋值

转载 作者:可可西里 更新时间:2023-11-01 08:25:31 27 4
gpt4 key购买 nike

我在查看前一段时间编写的一些代码时意识到我对 C# 中的赋值运算符做了一个假设。这是有问题的代码行(它按预期工作):

pointsChecked = pointsChecked ?? new List<Point>();

pointsChecked 是一个指定为递归函数参数的列表。它是一个默认参数,默认值为 null。我想要做的是将它初始化一次,然后构建一个我已经检查过的点集合,因此它应该只在第一次迭代期间初始化。

我的假设是 C# 以与 C++ operator= 应该在重载时提供保护相同的方式防止自赋值(即,if(这 == &rightHandSide) 返回 *this;)。但是,我无法找到任何资源明确说明这适用于 C#。

我找到的最接近的例子是 this question about the null-coalescing operator ,如果对象不是 null,它似乎将对象分配回自身。没有人对那个例子中的 self 赋值说任何话,但我想确定这不是一种不好的做法,并且没有负面影响。

Searching on MSDN我还发现(根据我的理解解释)右侧的值被复制到左侧的值并返回。因此,我再次不确定进行 self 分配是否是一件坏事。

我知道我可以做以下事情来提高安全性:

if(pointsChecked == null)
{
pointsChecked = new List<Point>();
}

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

最佳答案

赋值复制对对象的引用,而不是对象内容。从来没有任何可定制的代码作为对持有对象引用的变量的赋值的一部分运行。对于结构也是如此。

在 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

关于c# - C#中的自赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18815740/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com