そのようなクラスの属性内にget/setを持つという新しいアプローチでは:
public string FirstName {
get; set;
}
アクセサなしで属性FirstNameを単純にパブリックにしないのはなぜですか?
そのようなクラスの属性内にget/setを持つという新しいアプローチでは:
public string FirstName {
get; set;
}
アクセサなしで属性FirstNameを単純にパブリックにしないのはなぜですか?
クラス内の変数(フィールド/属性)への直接アクセスに関する2つの大きな問題は次のとおりです。
1)フィールドに対して簡単にデータバインドすることはできません。
2)クラスからパブリックフィールドを公開する場合、後でそれらをプロパティに変更することはできません(たとえば、セッターに検証ロジックを追加するため)
なぜなら、将来、実装を変更しても、現在のインターフェースを使用するコードは壊れないからです。
たとえば、パブリックフィールドを使用して単純なクラスを実装し、いくつかの外部モジュールでクラスの使用を開始します。1か月後、そのクラスに遅延読み込みを実装する必要があることがわかりました。次に、フィールドをプロパティに変換する必要があります。ciewの外部モジュールの観点からは、構文的には同じように見えるかもしれませんが、そうではありません。プロパティは関数のセットであり、フィールドはクラスインスタンスのオフセットです。
プロパティを使用することで、インターフェースが変更されるリスクを効果的に減らすことができます。
これは主に、一般的なコーディング規約になったことによるものです。必要に応じて、カスタム処理コードを簡単に追加できます。しかし、あなたは正しいです、技術的にこれの本当の必要はありません。ただし、後でカスタム処理を追加する場合は、インターフェイスを壊さないようにするのに役立ちます。
この表記法は、getter と setter のアクセシビリティを混在させる場合により便利です。たとえば、次のように記述できます。
public int Foo { get; private set; }
内部セッターを配置することも、ゲッターをプライベートにしてセッターをパブリックにすることもできます。
この表記により、内部的に書き込み可能/外部的に読み取り可能な値の古典的な問題を処理するためだけに、プライベート変数を明示的に書き込む必要がなくなります。
重要なのは、コンパイラが「内部」のプロパティを関数ペアに変換することです。プロパティを使用しているように見えるコードがある場合、ILにコンパイルすると実際に関数が呼び出されます。
したがって、これをフィールドとしてビルドし、このフィールドを使用する別のアセンブリにコードがあるとします。後で実装が変更され、コードの残りの部分から変更を非表示にするプロパティにすることにした場合でも、他のアセンブリを再コンパイルして再デプロイする必要があります。それが最初からのプロパティである場合、物事はうまくいくでしょう。
質問者はなぜ次のことをしないのかと尋ねていると思います...
public string FirstName { }
上記に短縮できるのに、なぜアクセサを気にするのですか。答えは、アクセサーを要求することで、コードを読んでいる人に、それが標準のget/setであることを明らかにすることだと思います。それらがなければ、これが自動的に実装されていることを見つけるのは難しいです。
99% のケースでは、パブリック フィールドを公開しても問題ありません。
一般的なアドバイスは、フィールドを使用することです。「クラスからパブリック フィールドを公開する場合、後でそれらをプロパティに変更することはできません」。私たちは皆、自分のコードが将来も保証されるものであることを望んでいることを知っていますが、この考え方にはいくつかの問題があります。
インターフェイスを変更すると、クラスのコンシューマが再コンパイルされる可能性があります。
データ メンバーの 99% が重要なプロパティになる必要はありません。それは投機的一般性です。おそらく決して役に立たないであろう多くのコードを書いています。
バージョン間のバイナリ互換性が必要な場合は、プロパティにデータ メンバーを作成するだけではおそらく十分ではありません。少なくとも、インターフェイスのみを公開し、すべてのコンストラクターを非表示にして、ファクトリを公開する必要があります (以下のコードを参照)。
public class MyClass : IMyClass
{
public static IMyClass New(...)
{
return new MyClass(...);
}
}
不確実な未来に機能するコードを作成しようとするのは難しい問題です。とても大変。
バグが発生し、どのメソッドがいつフィールドを変更しているかを調べる必要がある場合は、より多くのことを気にすることになります。軽量のプロパティアクセサーを前もって配置すると、ラップしたフィールドに関連するバグが発生した場合に、驚異的な量の心痛が軽減されます。私はそのような状況に数回ありましたが、特に再入可能性に関連していることが判明した場合は、快適ではありません。
この作業を前もって実行し、アクセサーにブレークポイントを設定することは、他の方法よりもはるかに簡単です。
オブジェクトのカプセル化を維持し、コードをより読みやすくします。