フィールドを外部に公開するのではなく、クラスフィールドのゲッターメソッドとセッターメソッド(C#のプロパティ)を作成してカプセル化を保護する必要があるとよく言われます。
しかし、フィールドが値を保持するためだけに存在し、取得または設定するために計算を必要としない場合が多くあります。これらのために、私たちは皆この番号をします:
public class Book
{
private string _title;
public string Title
{
get{ return _title; }
set{ _title = value; }
}
}
まあ、私は告白があり、すべてを書くことに耐えられませんでした(実際、それを書く必要はなく、それを見る必要がありました)。
次に、C#3.0が登場し、自動プロパティが追加されたことがわかります。
public class Book
{
public string Title {get; set;}
}
どちらがよりきれいで、私はそれを感謝していますが、実際には、単に公開フィールドを作ることと何がそんなに違うのですか?
public class Book
{
public string Title;
}
関連する質問 少し前に、いくつかの違いを説明するジェフのブログの投稿へのリンクがありました。
変数をプロパティに変更することは、重大な変更です。例えば:
TryGetTitle(out book.Title); // requires a variable
APIの問題を無視すると、プロパティの使用に関して最も価値があると思うのはデバッグです。
CLRデバッガーはデータブレークポイントをサポートしていません(ほとんどのネイティブデバッガーはサポートしています)。したがって、クラスの特定のフィールドの読み取りまたは書き込みにブレークポイントを設定することはできません。これは、特定のデバッグシナリオでは非常に制限されます。
プロパティは非常に薄いメソッドとして実装されるため、値の読み取りと書き込みにブレークポイントを設定することができます。これにより、フィールドに大きな足をかけることができます。
フィールドからプロパティに変更すると、契約が破られます(たとえば、すべての参照コードを再コンパイルする必要があります)。したがって、他のクラス(一般に保護されている)のメンバーとの対話ポイントがある場合、将来の成長を計画する必要があります。常にプロパティを使用してください。
今日それを自動プロパティにすることは何もありません。3か月後、遅延読み込みを行い、ゲッターにnullチェックを入れたいと気づきます。フィールドを使用したことがある場合、これは、アセンブリに依存している人と他の人に応じて、最高で再コンパイルの変更であり、最悪では不可能です。
誰もそれを言及しなかったからといって、インターフェイスのフィールドを定義することはできません。そのため、プロパティを定義する特定のインターフェイスを実装する必要がある場合、自動プロパティは本当に素晴らしい機能になることがあります。
しばしば見落とされ、他の回答には記載されていない大きな違い:オーバーライド。プロパティを仮想で宣言してオーバーライドすることができますが、パブリックメンバーフィールドに対して同じことはできません。
パブリックフィールドに対するプロパティの自動実装のもう1つの利点は、セットアクセサをプライベートまたはプロテクトに設定できることです。これにより、パブリックフィールドよりも優れた制御が定義されたオブジェクトのクラスを提供できます。
フィールドpublic
を作成しても問題はありません。しかし、private
フィールドを使用してgetter/setter
を作成することはカプセル化ではないことを忘れないでください。 IMO、Property
の他の機能を気にしない場合は、public
にすることもできます。
バージョン管理とAPIの安定性がすべてです。バージョン1では違いはありませんが、バージョン2で何らかのエラーチェックを行うプロパティを作成する必要があると判断した場合、APIを変更する必要はありません。プロパティの定義。
コレクションまたはデータベースと比較して、タイトルが一意であることを後で確認することにした場合、それに依存するコードを変更せずにプロパティでそれを行うことができます。
パブリック属性のみを使用すると、柔軟性が低下します。
契約を破ることのない柔軟性は、プロパティを使用する上で私にとって最も重要なものであり、実際に柔軟性が必要になるまで、自動生成は最も理にかなっています。
すべてのコードとテストの理由だけでなく、非常に便利だと思うことの1つは、プロパティとフィールドの場合、Visual Studio IDEはフィールドの参照ではなくプロパティの参照を表示することです。