不変のデータ型

不変オブジェクト
不変 (不変): つまり、オブジェクトが作成され初期化されると、メモリ内のこの型の値は決して変更されず、その後の変更ごとに新しいオブジェクトが生成されます。
不変型としての主な特徴は、一度作成されると、変更される限り、新しいオブジェクト インスタンスがマネージド ヒープ上に作成され、前のオブジェクト インスタンスに隣接し、連続したブロックに割り当てられます。マネージド ヒープ メモリ空間上。
例 1:
string str="zhjajihfgm";
str.Substring(0, 6)
C# の文字列は不変で、Substring(0, 6) は新しい文字列値を返し、共有ドメイン内の元の文字列は定数です。別の StringBuilder は変更可能であるため、StringBuilder が推奨されます。
例 2:
class Contact
{ public string Name { get; set; } public string Address { get; set; } public Contact(string contactName, string contactAddress) { Name = contactName; Address = contactAddress; } } var mutable = new Contact( "二毛"、"清華大学"); mutable.Name = "大毛";










mutable.Address = "北京大学";
Contact をインスタンス化し、それを mutable に割り当てます。その後、初期値ではなくなり、mutable オブジェクトと呼ぶことができる Contact オブジェクトの内部フィールド値を変更できます。
可変オブジェクトはマルチスレッド同時実行で共有されるため、いくつかの問題があります。マルチスレッドでは、スレッド A が Name = "Da Mao" に値を割り当てると、他のスレッドが読み取る可能性のあるデータは次のとおりです:
mutable.Name == "Da Mao";
mutable.Address == "Tsinghua";
明らかに、データは完全です 性的性が保証できず、データティアリングとも呼ばれます。次のように、可変オブジェクトを不変オブジェクトに変更します:
public class Contact2
{ public string Name { get; private set; } public string Address { get; private set; } private Contact2(string contactName, string contactAddress) { Name = contactName; Address = contactAddress; } public static Contact2 CreateContact(string name, string address) { return new Contact2(name, address); } }












使用する場合、名前フィールドとアドレス フィールドは Contact2 コンストラクターを通じてのみ初期化できます。Contact2 は、オブジェクト自体が不変の全体であるため、現時点では不変のオブジェクトです。不変オブジェクトを使用すると、データの整合性を心配する必要がなく、データのセキュリティも確保でき、他のスレッドによって変更されなくなります。

不変オブジェクトは次のとおりです:
string
ImmutableStack
ImmutableQueue
ImmutableList
ImmutableHashSet
ImmutableSortedSet
ImmutableDictionary
ImmutableSortedDictionary
は次のように使用されます、
ImmutableStack a1 = ImmutableStack.Empty;
ImmutableStack a2 = a1.Push(10);
ImmutableStack a3 = a2.Push(2) 0); 不変スタック
a4 = a3 .Push( 30);
ImmutableStack iv3 = a4.Pop();
Net 不変リスト コレクションを使用するときに注意すべき点の 1 つは、値をプッシュするときに、新しいオブジェクトが作成されるため、その値を元の変数に再代入するのが正しいということです。プッシュ後に元の a1 が生成されます。古い値だけです:
ImmutableStack a1 = ImmutableStack.Empty;
a1.Push(10); //不正解、a1 はまだ空の値であり、プッシュにより新しいスタックが生成されます。a1 = a1.Push(10); //新しいスタックを a1不変オブジェクト
に再割り当てする必要がある利点コレクションの共有は安全であり、変更されることはありませんコレクションにアクセスするときに、コレクションをロックする必要はありません (スレッド セーフ)。古いコレクションが破壊されることを心配する必要はありません。




データの整合性、セキュリティの保証
不変オブジェクト
短所 オブジェクト/コレクション操作ごとに新しい値が返される場合。古い値が一定期間保持されるため、メモリのオーバーヘッドが大きくなり、GC に回復の負担がかかり、可変コレクションよりもパフォーマンスが低下します (約 40 倍の差)。
string や StringBuild と同様に、Net が提供する不変コレクションにも、大量のオブジェクトの作成を避けるためのバッチ操作 API が追加されています:
ImmutableList immutable = ImmutableList.Empty;
// バッチで操作できるコレクションに変換します
var immutable2 = immutable. ToBuilder( );
immutable2.Add("xx");
immutable2.Add("xxx");
//不変コレクションに戻す
immutable = immutable2.ToImmutable();

ここでは主に、Thunder に似たダウンロード タスク、元に戻す操作による操作の記録に使用されるコレクションなど、不変コレクションの主なアプリケーション シナリオについて説明します。このようなシナリオでは、通常、いずれかの要素の内容は編集されず、要素の操作頻度も頻繁ではありませんが、同時に、ロック操作によるプログラムのパフォーマンスへの影響を回避するマルチスレッドの安全性も満たします。

おすすめ

転載: blog.csdn.net/qq_37619255/article/details/130058804