c# - BigInteger 是否不可变?

标签 c# .net immutability biginteger fcl

在 .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/

相关文章:

c# - Windows 商店应用程序中的登录屏幕 - MessageDialog

c# - SQL Server XML 数据类型在 .NET 中转换成什么?我如何将它转换成 XmlDocument?

java不可变类慢得多

java - 使用多个构造函数创建不可变类

c# - 取消 C# 表单的关闭

c# - 不安全代码无法在 Visual Studio 2015 上编译

c# - 从 EWS 访问 Outlook 用户属性

c# - 在 ExtDateOnly 中禁用日期

.net - 在 Windows Vista 中 reshape "glass"

java - 将 Map 转换为 ImmutableSetMultimap