2009-07-25 9 views
272

フィールドを外部に公開するのではなく、クラスフィールドのgetterメソッドとsetterメソッド(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;} 
} 

整然とあり、私はそれのために感謝していますが、実際には、単に公共の場を作るよりも大きく異なる何ですか?

+0

[C#.NETのプロパティとフィールドの違い3.5+]の可能な重複(http://stackoverflow.com/questions/653536/difference-between-property-and-field-in-c-sharp-net- 3-5) – nawfal

+4

私はフィールドをプロパティに変換したので、セッターにブレークポイントを設定することができます –

+1

私はプロパティをフィールドにリファクタリングする必要がある道を実現するため、プライベートではないものを作る傾向があります不必要な頭痛につながります。 [プロパティ、フィールド、およびメソッド。 Oh My!](http://www.codeducky.org/properties-fields-and-methods-oh-my/)は過去に私に噛まれた非互換性を呼び出す。 –

答えて

137

私はしばらく前に、Jeffのブログに投稿のリンクがあり、いくつかの違いを説明していました。

Properties vs. Public Variables

  • リフレクションは、性質対変数に異なる動作をするので、あなたは反射に依存している場合、それはすべてのプロパティを使用する方が簡単です。
  • 変数に対してデータバインドすることはできません。
  • 変数をプロパティに変更することは大きな変更です。たとえば:

    TryGetTitle(out book.Title); // requires a variable 
    
+17

「変数をプロパティに変更することは大きな変更です」これはもちろん、ほとんどの開発者がやっていない再利用可能なライブラリを書くときにのみ当てはまります。 – Steven

+21

また、プロパティは、自動プロパティでさえ、フィールドではできないバーチャルにすることができます。したがって、ベースクラスは自動小道具のためにコンパイラによって生成される単純なバッキングフィールド実装を持つことができ、派生クラスは追加の検証やその他のロジック/計算を実行できます。 – KeithS

+22

また、フィールドは_variable_であり、参照( 'ref'または' out'キーワード)によって渡すことができますが、プロパティはアクセサのペアであり、参照渡しできません。たとえば、 'bool success = TryGetMyTitle(out myBook.Title);' out'を使うと、フィールドでは動作し、プロパティでは動作しません。これは、フィールドからプロパティへの変更が大きな変化である理由の明確な例です。 –

51

フィールドをプロパティに変更すると、契約が破損します(たとえば、すべての参照コードを再コンパイルする必要があります)。したがって、他のクラス(一般に保護されているメンバー)とのやりとりポイントを持つ場合、将来の成長を計画したいと考えています。常にプロパティを使用してください。

今日は自動プロパティにすることは何もありません。ラインを3ヶ月下に置くと、遅延ロードされ、ゲッターにヌルチェックを入れたいと分かります。フィールドを使用していた場合、再コンパイルの変更は最善であり、最悪の場合は不可能です。&には、アセンブリに依存しているものがあります。

+1

「回答」、「インターフェース」、「上書き」という言葉を使用していないため、この回答が気に入っています。 (「契約」についてはあまりにも悪い) –

6

これは、すべてのバージョン管理とAPIの安定性についてです。バージョン1では違いはありませんが、後でバージョン2で何らかのタイプのエラーチェックを行い、これをプロパティにする必要がある場合は、APIを変更する必要はありません。プロパティの定義。

64

APIの問題を無視して、プロパティの使用について最も価値のあるものはデバッグです。

CLRデバッガはデータブレークポイントをサポートしていません(ほとんどのネイティブデバッガがサポートしています)。したがって、クラス上の特定のフィールドの読み取りまたは書き込みにブレークポイントを設定することはできません。これは特定のデバッグシナリオでは非常に限定的です。

プロパティは非常に細いメソッドとして実装されているため、値の読み取りと書き込みにブレークポイントを設定することができます。これは彼らにフィールド上の大きな足を与えます。あなたはタイトルがコレクションやデータベースと比較することにより、ユニークであることを確認するために、後で決定した場合

0

は、あなたはそれに依存して任意のコードを変更せずに、プロパティにそれを行うことができます。

公開属性だけを使用すると、柔軟性が低下します。私は実際に柔軟性が必要になるまで

契約を壊すことなく、余分な柔軟性は、プロパティの使用方法についての私に最も重要なものである、と、自動生成は、最も理にかなっています。

53

これは誰も言及していないからです。インターフェイスにフィールドを定義することはできません。したがって、プロパティを定義する特定のインターフェイスを実装する必要がある場合、自動プロパティは時には本当に便利な機能です。

+1

プロパティを定義するインターフェイスが必要な場合は、抽象クラスにする必要があります。 C#ではインターフェイスのプロパティを定義できるため、それらを使用する必要はありません。それは悪いデザインです。 – Odys

+6

@odyodyodys - これは悪いデザインだと私は同意していません。あなたの根拠を説明してください。 –

+3

@odyodyodys私はzooone9243に同意します:デザインの観点から見ると、プロパティの宣言とゲッター/セッターのペアの宣言(これはインターフェースの一般的なプラクティスです)の違いはありません。 – MartinStettner

7

フィールド作成に間違いはありません。publicしかし、getter/setterとのフィールドを作成することはカプセル化されていないことを忘れないでください。 IMO、Propertyの他の機能について気にしない場合は、publicとすることもできます。

41

多くの見落としがあり、他の回答では言及されていない大きな違い:は、を上書きします。パブリックメンバーフィールドでは同じことをすることはできませんが、プロパティを仮想宣言してオーバーライドできます。公共分野にわたる

9

自動実装プロパティのもう一つの利点は、あなたがそれが公共の場のそれよりも優れたコントロールを定義したオブジェクトのクラスを提供する、一連のアクセサはプライベートまたは保護させることができるということです。

0

一つ、私は非常に便利なものだけでなく、すべてのコードとテストの理由は、それがフィールド対財産である場合にはVisual StudioのIDEがあなたの財産についての言及はなく、フィールドを示すことであるということです。

関連する問題