2009-10-28 15 views
9

.NET 4ベータ2では、新しいNumericsネームスペースがstruct BigIntegerです。 documentationは、私が予期していたように不変型であると述べています。BigIntegerは不変かどうか?

しかし、ポストインクリメント演算子(++)は少し混乱しています。これは価値が変異しているように見えます。以下のwhileループは動作します:BigIntegerのオブジェクトは不変 なので、インクリメント演算子 が 新しいBigIntegerのオブジェクトを作成します

static BigInteger Factorial(BigInteger n) 
{ 
    BigInteger result = BigInteger.One; 
    BigInteger b = BigInteger.One; 

    while (b <= n) 
    { 
     result = result * b; 
     b++; // immutable ? 
    } 
    return result; 
} 

これは、MSDNはインクリメント演算子について言いたいことがあるものですvalueは、valueで表されるBigInteger オブジェクトの1つです。 したがって、インクリメント への繰り返し呼び出しは高価になる可能性があります。

すべてが順調と罰金、私は、それ自体でb = b++どうやら++を使用していた場合には、値を変更するのに十分です理解しているだろう。

どのような考えですか?

編集:
Lasseが指摘しているように、ポストインクリメントの仕組みについては、step-by-step specificationがあります。しかし、これはまだ変わらないと思われます。たとえば、この演算子を使用するとスレッドセーフであるとは思いません。コメントし、このかもしれませんが、今

var temp = b; 
b = b + 1; 
<use temp for the expression where b++ was located> 

b++; 

は同等です:現実になるよう

答えて

13

オペレーター++--は、通常の+-オペレーターの面で実装されていますそれは不変を破るようだが、そうではない。

あなたが代わりにこれを行うと、このコードを見てください。これは、メモリ内の2つのオブジェクトを残すだろう

var temp = b; 
b = BigInteger.op_Add(b, 1); // constructs a new BigInteger value 
<use temp ...> 

、今bで参照元のBigInteger値、および新しいもの、。あなたは簡単に、これは次のコードで何が起こるかであることを確認することができますので、それは不変性を破壊しない、との質問の新しい部分に答えるために、

var x = b; 
b++; 
// now inspect the contents of x and b, and you'll notice that they differ 

だから、元のオブジェクトが変更されていない、これはスレッドでなければなりません-安全。

これは、文字列にたまたま同じものです:BigIntegerのは不変なので++がちょうど等しくなるB、

String s1 = s2; 
s2 += "More"; 
// now inspect s1 and s2, they will differ 
+0

妥当と聞こえるが、それでも変わらないようだ。私は少し質問を編集します。 –

+1

いいえ、それは不変を破らない、私の答えを更新させてください。 –

+2

's + = s2'には目に見える割り当てがあります。あなたが 'b ++ 'も代入、つまり' b = b + 1'であると受け入れるなら、それは合っています。しかし、「++」はまだ変わっているように感じます。 –

3

:この操作後に

BigInteger temp=b; 
b=temp+1; 

、一時はGCによってリサイクルされますメモリが解放されます。

+1

OK、GC部分を除く。構造体(内部配列を持つ)です。 –

+0

はい、唯一の違いは、このクラスがヒープに格納されている間は、構造体がスタックに格納されることです。 –

+0

Ted、オブジェクトのBigIntegerフィールドはどこに格納されていると思いますか? –

関連する問題