根据 MSDN,System.Int32 是不可变的,其成员总是返回新实例。 一些常见的代码,比如 for 循环,经常需要++ 操作。 increment 是否总是创建新实例并丢弃旧实例?据我所知,这种方法会严重影响性能。我想知道 Microsoft 如何实现它。
顺便问一下,increment 是线程安全的吗?在文档中,它说 Int32 的所有成员都是线程安全的,但是有 interlocked.increment()。
谢谢。
最佳答案
是也不是。
答案是肯定的,因为:
i++;
等同于:
i = i + 1;
这将等同于此(如果 System.Int32
具有具有此签名的构造函数):
i = new int(i + 1);
但是...
.NET 中值类型的构造函数绝不与引用类型构造函数相同。
值类型的空间在堆栈上分配一次。当您编写 i = i + 1
时,这只是将一个新值写入内存中的相同位置。它不是堆上的新分配。
这实际上是一个实现细节;但这并没有改变一个事实,即我认为您真正要问的问题的答案——“编写 i++
是否需要在某处分配一些新内存?” -- 那个问题的答案是否定的。
所以,澄清几点:
Does increment always create new instances and discard the old ones?
不——这表明了对值类型工作方式的误解。如果值类型分配在本地堆栈以外的某个空间中,那么说递增一个值“丢弃旧值”才有意义。旧值确实被覆盖,但我认为您不会对此感到惊讶。
By the way, is increment thread-safe? In documentation, it says all the members of Int32 are thread-safe . . .
文档中说 Int32
的所有成员都是线程安全的,这意味着相对于当前值。事实上,任何不可变类型都将是线程安全的,因为如果它不能被修改,那么它就不会被破坏。
您必须意识到 i++
不仅仅是对某些 i
值的方法调用;它是 i
对新值的赋值。这个操作——将 i
分配给一个新的增量值——是不是线程安全的,因为两个线程可能同时执行这个代码,你可以结束i
的新值仅比先前值大 1。这就是 Interlocked.Increment
的用途。但是 MSDN 文档并没有骗你; i
的内部状态不会受到多线程访问的影响。
关于c# - operator++ (int x) 是否每次都创建新实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3540038/