この回答から、KeyValuePairは不変であることがわかりました。
ドキュメントを閲覧しましたが、不変の動作に関する情報が見つかりませんでした。
型が不変であるかどうかを判断する方法を考えていましたか?
C#には不変性の公式な概念がないため、これを行うための標準的な方法はないと思います。私が考えることができる唯一の方法は、特定のものを見ることであり、より高い確率を示しています。
1)タイプのすべてのプロパティにはプライベートがありますset
2)すべてのフィールドはconst
/readonly
またはプライベートです
3)明らかな/既知の副作用を持つ方法はありません
4)また、構造体であることは一般的に良い兆候です(BCLタイプであるか、このためのガイドラインを持っている人による場合)
のようなものImmutabeAttribute
がいいでしょう。ここ(コメントのどこか)にいくつかの考えがありますが、私はまだ「実生活」でそれを見ていません。
最初の兆候は、概要のプロパティのドキュメントに「キーと値のペアのキーを取得する」と記載されていることです。2番目に明確な兆候は、プロパティ自体の説明にあります。
ドキュメントを見るだけでは不変性の「証拠」を見つけることができないと思いますが、いくつかの強力な指標があります。
struct
(なぜこれが重要なのですか?)確実な証拠として、MicrosoftからBCLの参照ソースをダウンロードするか、ILデコンパイラーを使用して、コードで型がどのように表示されるかを示すことをお勧めします。
AKeyValuePair<T1,T2>
は、Reflectionがない場合KeyValuePair<T1,T2>
、目的の値を保持する別のコンテンツをコピーすることによってのみ、コンストラクターの外部で変更できる構造体です。次のステートメントに注意してください。
MyKeyValuePair = new KeyValuePair(1,2);
構造体に対するすべての同様のコンストラクター呼び出しと同様に、実際には、の新しい一時インスタンスを作成しKeyValuePair<int,int>
(コンストラクター自体が実行される前に発生します)、そのインスタンスのフィールド値を設定し(コンストラクターによって実行されます)、その新しい一時インスタンスのすべてのパブリックフィールドとプライベートフィールドをコピーします。インスタンスをMyKeyValuePair
に変換してから、一時インスタンスを破棄します。
次のコードを検討してください。
static KeyValuePair MyKeyValuePair; //あるクラスのフィールド //スレッド1 MyKeyValuePair = new KeyValuePair(1,1); // *** MyKeyValuePair = new KeyValuePair(2,2); //スレッド2 st = MyKeyValuePair.ToString();
は正確に4バイトの長さであるためMyKeyValuePair
、Thread1の2番目のステートメントは両方のフィールドを同時に更新します。それにもかかわらず、Thread1の2番目のステートメントがThread2のとの評価の間に実行される場合、最初のステートメントが変更前のMyKeyValuePair.Key.ToString()
値で動作したとしてもMyKeyValuePair.Value.ToString()
、 2番目のステートメントToString()
は構造の新しい変更された値に作用しますToString()
。
自明でないすべての構造体は、宣言方法に関係なく、フィールドに対して同じ不変性ルールを持っています。構造体を変更できるコードは、そのフィールドを変更できます。構造体を変更できないコードは、そのフィールドを変更できません。一部の構造体は、フィールドの1つを変更するためにフープを通過するように強制する場合がありますが、インスタンスの不変性を保証するには、構造体タイプを「不変」に設計する必要も十分でもありません。「不変」構造体タイプの合理的な使用法はいくつかありますが、公開フィールドが公開されている構造体に必要なものよりも注意が必要な場合は、このような使用例があります。