web-dev-qa-db-ja.com

データにパブリックプロパティとプライベートフィールドまたはパブリックフィールドを使用する必要がありますか?

私が見たコードの多く(SO、thecodeproject.comおよび私は自分のコードでこれを行う傾向があります)で、クラスに含まれるすべてのプライベートフィールドに対してパブリックプロパティが作成されていることを確認しましたget; set;の基本的なタイプ:

private int myInt;
public int MyInt 
{
     get { return myInt; }
     set { myInt = value }
}

私の質問は、これはどのように違うのですか?

public int MyInt;

パブリックフィールドの代わりにプロパティを使用する必要がある場合、なぜこの特定のケースでプロパティを使用する必要があるのでしょうか。 (私は、ゲッターとセッターが実際に特別なことをする、またはプライベートフィールドの値を返す/設定するのではなく、1つだけ取得または設定(読み取り/書き込みのみ)する、より複雑な例について話していません)。それは余分なカプセル化を追加するようではなく、IntelliSenseにニースアイコンを与え、クラス図の特別なセクションに配置されます!

55
Callum Rogers

この記事を参照してください http://blog.codinghorror.com/properties-vs-public-variables/

具体的には

  • リフレクションは変数とプロパティでは動作が異なるため、リフレクションに依存している場合は、すべてのプロパティを使用する方が簡単です。
  • 変数に対してデータバインドすることはできません。
  • 変数をプロパティに変更すると、重大な変更になります。
33
Johnno Nolan

3つの理由:

  1. プロパティのようにサブクラスのフィールドをオーバーライドすることはできません。
  2. 最終的には、より複雑なgetterまたはsetterが必要になる可能性がありますが、それがフィールドの場合、変更するとAPIが壊れます。
  3. コンベンション。それがまさにそのやり方です。

考えていない理由は他にもあると思います。

.Net 3.xでは、次のような自動プロパティを使用できます。

public int Age { get; set; }

古いフィールドの代わりに、自分のプライベートフィールドを次のように宣言します。

private int age;

public int Age
{
    get { return age; }
    set { age = value; }
}

これにより、フィールドを作成するのと同じくらい簡単になりますが、特に変更の問題は発生しません。

22
Max Schmeling

プライベートフィールドnameと、実際にnameフィールド値を取得および設定する単純なパブリックプロパティNameを作成する場合

public string Name
{
   get { return name; }
}

そして、このプロパティをクラスの外のあらゆる場所で使用し、ある日、このクラスのNameプロパティが実際にlastNameフィールドを参照することを決定した(または、文字列 "My name:" + name)、プロパティ内のコードを変更するだけです:

public string Name
{
   get { return lastName; //return "My name: "+name; }
}

パブリックフィールドnameを外部コードのすべての場所で使用している場合は、使用したすべての場所でnamelastNameに変更する必要があります。

8
agnieszka

まあそれは違いを生みます。パブリックデータは、オブジェクトインスタンスが認識していなくても変更できます。ゲッターとセッターを使用すると、オブジェクトは常に変更が加えられたことを認識します。

データのカプセル化は、より構造化された設計に向けた最初のステップにすぎず、それ自体が最終目標ではないことに注意してください。

5

次の場合にプロパティを使用する必要があります。

  1. プロパティのデータを何らかの形式にシリアル化する必要がある場合。
  2. 派生クラスのプロパティをオーバーライドする必要がある場合。
  3. いくつかのロジックを使用してgetおよびsetメソッドを実装する場合。たとえば、シングルトンパターンを実装する場合です。
  4. プロパティが宣言されたインターフェイスから派生した場合。
  5. Reflectionに関連する特定の問題がある場合。
4

場合によります?

彼らはこのショートカットを作成したので、私は常にゲッターとセッターを使用します:

public int Foo {get;セットする; }

コンパイル時に翻訳されます。さて、あなたはそれで空想を得ることができませんが、それはそこにあります、そしてあなたが空想を得る必要があるならば、あなたは後でそれを綴るだけです。

ただし、パブリック、プライベート、保護されている...データを微調整できるようにしたい人はすべて問題です。私たちは継承をよく使用しますが、これは私たちにとって非常に一般的な方法であるため、子供だけが特定のプロパティを編集できます。

protected _foo;  
public Foo  
{  
    get { return _foo; }
} //lack of set intentional.
2
Russell Steen

簡単に言うと、質問への答えはアクセス修飾子、つまりパブリックとプライベートです。

使用する場合:

public int myInt;
public int MyInt 
{
     get { return myInt; }
     set { myInt = value }
}

次に、変更するプロジェクトでMyIntプロパティとmyInt変数の両方を使用できます。つまり、AがBのクラスによって継承されていると仮定した場合、myIntとMyIntの両方を変更でき、チェックを適用できません。特定の条件に合格した場合に、派生クラスにmyInt値を設定できるようにするとします。

これは、フィールドをプライベートにし、プロパティをパブリックにすることによってのみ達成できます。そのため、プロパティのみが使用可能であり、それに基づいて条件を設定できます。

0
KamalDeep

理由はたくさんあります。

主に:

  • 変数を設定すると、他のいくつかの機能を実行できます
  • 設定を防ぎ、取得のみを提供できます
  • 一部の「もの」はプロパティでのみ機能します(DataBindingなど)
  • プロパティの実装を非表示にすることができます(おそらくASP.NETではViewState変数です)。
0
Noon Silk

ポイントは、myIntが参照されるたびに特別な何かが発生することを確認したい場合(ログファイルが書き込まれ、ログファイルが42に変更されるなど)です。ゲッターとセッターなしではそれはできません。時には、今必要なものではなく、必要なものをプログラムすることが賢明な場合があります。

0
Dominic Rodger

実際、Silverlightを使用している場合は、フィールドに静的リソースを設定できないため、プロパティを使用する必要があります(constにアクセスする場合でも)。

複合ガイダンス(PRISM)で使用する地域名を統合しようとしたときに気付きました。

ただし、これは言語の制限にすぎず、static/constフィールドとは別に、常にプロパティを使用します。

0
R4cOOn

外部のクラスのプライベートフィールドの値を誤って/誤って変更しないでください。 getおよびsetを使用する場合、それは、クラスのプライベートフィールドを意図的かつ意図的に変更していることを意味します。

0
rayimag

プライベートフィールドに値を設定すると、そのフィールドのみが変更されますが、プロパティでそれらを作成すると、別の引数を処理できます。たとえば、値を設定した後にメソッドを呼び出すことができます

 private string _email; 
 public string Email 
 {
 get 
 {
 return this._email; 
 } 
 set 
 {
 this._email = value; 
 ReplaceList(); //**
} 
} 
 
 
 
 
0
Myra