以下を行うことは良い/悪い習慣ですか?
public class MyClass {
public MyType MyProperty { get; private set; }
public void SetMyProperty(MyType myProperty) {
MyProperty = myProperty;
}
}
私の意図は、クラスの外でMyProperty
が誤って変更されないようにすることです。ただし、必要に応じて変更できます。
また、MyType
が参照型の場合、private set
防止、例えば:
instanceOfMyClass.MyProperty.SomeField = 2;
つまり、MyProperty
とそのすべてのメンバーを読み取り専用にしますか、それともMyProperty
への参照だけにしますか?
これがインテリジェントな質問ではないようでしたら申し訳ありません。私は初心者だと思います。
私の意図は、クラス外でMyPropertyが誤って変更されないようにすることです。ただし、必要に応じて変更できます。
正直なところ、これを行う意味はわかりません。呼び出す
myClass.MyProperty = new MyType();
呼び出すよりも意図的ではありません
myClass.SetMyProperty(new MyType());
読みやすさの点では、個別のメソッドではなく、より直感的なセッターアプローチのほうがはるかに良いと思います。そして、誰かがMyProperty
の値を変更できるようにしたくない場合は、セッターまたはメソッドを介して許可しないでください。
つまり、MyPropertyとそのすべてのフィールドを読み取り専用にしますか、それともMyPropertyへの参照だけにしますか?
MyProperty
への参照のみ。 MyType
は、人々がそのプロパティを変更できないようにする場合、 不変タイプ である必要があります。
プライベートセッターを持つことは完全に有効な慣行であり、私はこれを自分で行うことがよくあります。これは、OOPの基礎の1つであるカプセル化の一部です。
ただし、設定にパブリックメソッドを提供しても意味がありません。値を設定できるようにするには、パブリックセッターを使用します。
あなたが尋ねたように、プライベートセッターを使用しても、基になるフィールドの値をクラスの外で変更することはできません(コンパイラーが生成します-基になるフィールドはまだあります)。これは、この値を変更するパブリック関数を提供しない限りです。
「SetProperty」メソッドを終日使用したい場合は、Javaでプログラミングします。
さらに、パブリックgetプロパティがある場合、そのプロパティにプライベートセットがある場合でも、プロパティの値のメンバーを変更できます。多くの配列クラスなど、一部のクラスはこの問題を解決するために「読み取り専用」ラッパーを提供します。 http://msdn.Microsoft.com/en-us/library/53kysx7b.aspx
ゲッターを提供しても、クラスのプロパティを変更できます。あなたがそれを避けたいなら、私はインスタンスをクローンします
private MyType _myProperty;
public MyType MyProperty { get { return new MyType(_myProperty); } set { _myProperty = value; } }
何かが読み取り/書き込みプロパティとして動作する場合、通常は読み取り/書き込みプロパティを使用して実装する必要があります。一方、プロパティの値を変更できるという事実は、読み取り/書き込みプロパティのように動作することを意味しません。一般に、何かが「クリーン」プロパティとして機能する場合は、読み取り/書き込みプロパティとしてのみ実装する必要があることをお勧めします(以下で説明)。ただし、.Netの多くのクラスは、私が提案するものに適合しない。多くの場合、これは完全な哲学的背景が完全に解明される前にフレームワークを実装するようにという時間的なプレッシャーに起因すると推測します。
以下の場合、読み書きプロパティはクリーンであると見なします。
「クリーン」プロパティへの書き込みが他の読み取り専用プロパティの状態に影響を与えることは完全に許容されることに注意してください。複数のプロパティを設定した場合の影響は、書き込まれた値に依存しますが、書き込みが発生する順序には依存しません。 myRect
が(X = 1、Y = 2、Width = 3、Height = 4)に初期化されている場合、MyRect.X=2; MyRect.Top = MyRect.Right;
の効果は、MyRect.X = 2; MyRect.Top = 5;
またはMyRect.Top = 5; MyRect.X = 2;
と同じでなくても、同じでなければなりません。 MyRect.Top = MyRect.Right; MyRect.X = 2;
として。
多くの.netクラスは、これらの定義による「不明瞭」な方法でプロパティを使用します。たとえば、これらの定義を使用すると、StringBuilder .Length
はおそらく読み取り専用プロパティになりますが、Text
はおそらく読み取り/書き込みプロパティになる可能性があります(Text
の読み取りは同等です) ToString()
に書き込みますが、書き込み中はそれをクリアしてAppend
)を実行するのと同じです。
オブジェクトのプロパティを変更できるさまざまな状況がありますが、それらは「クリーンな読み取り/書き込みプロパティ」と見なすべきではありません。その中で:
これらの条件のいずれか(または他の多くのリスト-リストがほとんど網羅されていない場合)が適用される場合は、読み取り/書き込みプロパティではなくSetXX
メソッドを使用します。