在 .NET 4 beta 2 中,有带有 struct BigInteger
的新 Numerics 命名空间。 documentation声明它是一个不可变类型,正如我所预料的那样。
但我对后增量运算符 (++
) 有点困惑。这肯定会改变值(value)。以下 while 循环有效:
static BigInteger Factorial(BigInteger n)
{
BigInteger result = BigInteger.One;
BigInteger b = BigInteger.One;
while (b <= n)
{
result = result * b;
b++; // immutable ?
}
return result;
}
这是 MSDN 对增量运算符的描述:
Because BigInteger objects are immutable, the Increment operator creates a new BigInteger object whose value is one more than the BigInteger object represented by value. Therefore, repeated calls to Increment may be expensive.
很好,如果我必须使用 b = b++
我会理解,但显然 ++
本身就足以改变一个值。
有什么想法吗?
最佳答案
运算符 ++
和 --
是根据普通的 +
和 -
运算符实现的,所以在现实中:
b++;
相当于:
var temp = b;
b = b + 1;
<use temp for the expression where b++ was located>
现在,正如所评论的那样,这似乎破坏了不变性,但实际上并没有。
您应该将此代码视为这样做:
var temp = b;
b = BigInteger.op_Add(b, 1); // constructs a new BigInteger value
<use temp ...>
这将在内存中留下两个对象,原始的 BigInteger 值和新的,现在由 b 引用。您可以轻松检查以下代码是否会发生这种情况:
var x = b;
b++;
// now inspect the contents of x and b, and you'll notice that they differ
所以原始对象没有改变,因此它不会破坏不变性,并且要回答问题的新部分,这应该是线程安全的。
这与字符串发生的事情相同:
String s1 = s2;
s2 += "More";
// now inspect s1 and s2, they will differ
关于c# - BigInteger 是否不可变?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1635949/