【C#】構造体の防衛的コピー

構造体の防衛的コピー

構造体は値型であり、値への参照ではなく値そのものを持っている。

構造体型のフィールドに対してreadonlyを付ける(または読み取り専用(get-only)プロパティを使用する)と、構造体の値そのものが読み取り専用となり、フィールドの書き換えはできなくなる。

しかし、メソッドの呼び出しについては制限されない。そのため、メソッド内で値が変更されてしまう懸念がある。

実際には、このとき別の場所にフィールドの値がコピーされ、そのコピーがメソッドを呼ぶことになる。

結果として、もとの構造体は変更されずreadonlyが保たれる。

この挙動はメソッド内で値が書き換えられる可能性があるための措置であり、これを防衛的コピーという。

メソッド内で値を変更していなくても防衛的コピーは行われる。(コンパイラがメソッド内で値を変更しているかしていないかの区別ができないため)

以下の例のようにMap2内でPointが生成される場合も、防衛的コピーは機能する。

メソッドを呼び出すとLocationがコピーされ、そのコピーからメソッドが呼ばれる。

thisによる読み取り専用フィールの書き換え

構造体ではフィールドを読み取り専用にしていても、thisを置き換えることで書き換えできてしまう。

C# 7.2以降ではreadonly structが使えるので、構造体自体を読み取り専用にすることができる。

readonly structを使えば、thisも読み取り専用なるためthisによる書き換えの問題は起こらない。

コメント

タイトルとURLをコピーしました