15

重複の可能性:
C# のフィールドとプロパティの違いは何ですか

私はプログラミング初心者で、クラス プロパティについてはすべて読んだことがあります。本には、プロパティを使用するとメンバー変数に間接的にアクセスできると記載されています。では、フィールドを公開して直接アクセスすることと何が違うのでしょうか?

以下は、Jesse Liberty による Learning C# 3.0 からの引用です。

たとえば、外部クラスで値を読み取ることはできても変更できないようにする場合があります。または、内部フィールドが特定の範囲の値のみを受け入れるようにコードを記述したい場合があります。外部クラスにメンバー フィールドへの自由なアクセスを許可すると、それを制御することはできません。

彼がここで何を言っているのかわからない。誰かがこれをさらに説明したり、フィールドを公開するよりもプロパティを使用したい理由の例を挙げたりできますか? 私が今理解しているように、どちらもまったく同じことを達成するでしょう...だから、明らかに何かが欠けています。

4

6 に答える 6

11

これまでに提供された他の回答は、アクセサー/ミューテーター ロジックの利点の詳細を提供しますが、すべてオブジェクトのカプセル化に関するイデオロギー ポイントを見逃しているようです。

ご覧のとおり、クラス メンバー フィールドは実装の詳細です。たとえば、コレクションを表すクラスがある場合、それをリンク リストとして実装する (そしてパブリック フィールドを介してルート ノードを公開する) か、サイズ変更可能な配列として実装し、index0 メンバーを公開することができます。

実装の詳細を公開する際の問題は、クラスとそのコンシューマーの間で定義されたあらゆる種類のインターフェイスが失われることです。すべての操作が定義済みのメソッド (クラス自体によって制御される) を介して行われるようにすることで、作業が容易になり、長期的な視点が提供されます。たとえば、クラスのコンシューマーとの契約を破棄することなく、コレクションの実装をある型 (リンク リスト) から別の型 (配列) に変換することがはるかに簡単になります。

単純なアクセサー/ミューテーター メソッドのパフォーマンスへの影響について心配する必要はありません。JIT コンパイラーはプロパティ メソッドをインライン化します。いくつかのベンチマークを実行すると、プロパティとフィールドのパフォーマンスが同じであることがわかります。

于 2012-08-08T23:07:52.077 に答える
10

彼は、プロパティはゲッターを提供できるがセッターは提供できないため、読み取り専用にすることができると言っています(たとえば)

プロパティは、メソッドの単なる構文糖衣です。

public int SomeProperty { get; set; }

砂糖だけです

private int _someProperty;

public int SomeProperty_get() 
{
   return _someProperty;
}

public void SomeProperty_set(int value) 
{
   _someProperty = value;
}

これは、プロパティセッター/ゲッターが単なるパブリックフィールドでは不可能なロジックを適用できることを意味します

編集:CLRが自動プロパティのバッキングフィールドに与えるフィールド名は正確にはわかりません-これは単なる例です:)

Edit2:

読み取り専用プロパティの例:

public int SomeProperty { get; }

そして最後にパブリック読み取り-プライベート書き込み(自動プロパティ用)

public int SomeProperty { get; private set; }

わざわざバッキングフィールドを入力することができない場合に本当に便利です:)

メンバーにロジックを適用したい可能性がある場合は、プロパティが最適です。これは、多くのフレームワークが機能する方法です(たとえば、プロパティを使用して「ダーティ」オブジェクトを追跡し、ある種のオブジェクトマネージャーに何かが変更されたことを通知します。これは、パブリックフィールドでは不可能です)。

于 2012-08-08T22:59:00.420 に答える
9

プロパティには副作用があります。これらは、「getter」メソッドと「setter」メソッドの周りに構文糖衣構文を提供します。

public class MyClass {

   int sizeValue = 0;

   public int Size {
      get {
         return sizeValue;
      }
      set {
         if ( value < 10 ) throw new Exception("Size too small");
         sizeValue = value;
      }
   }
}

プロパティには、getとsetに対してさまざまなレベルの保護を設定することもできますが、フィールドではそれを行うことはできません。

public class MyOtherClass {

   // only this object can set this.
   public int Level {
      get; private set; 
   }

   // only things in the same assembly can set this.
   public string Name {
      get; internal set;
   }
}
于 2012-08-08T22:58:15.303 に答える
3

「プロパティ」と「メンバーアクセス」の間には、いくつかの重要な違いがあります。

最も重要なのは、プロパティを介して、メンバーを読み取り専用にすることができることです(状態にアクセスすることはできますが、変更することはできません)。Javaの「getter()」および「setter()」メソッドと同じです。

プロパティから計算値を返すこともできます(変数であるかのように「オンザフライ」で値を生成します)。

于 2012-08-08T22:57:26.707 に答える
1

プロパティは、次のように構成できます。

それらは読み取り専用であり、Public MyProp {get;}

それらは書き込み専用ですPublic MyProp {set;}

それらは外部オブジェクトから読み取り可能ですが、クラスの内部によってのみ設定できます

公衆MyProp {get; private set;}

他の人が投稿したように、ゲッターとセッターにロジックを入れることもできます。たとえば、プロパティを新しい値に設定することを許可する前に、その値が許容できるかどうかを確認できます。

public フィールドではそれを行うことはできません。

基本的に、パブリック フィールドは、所有できる最もばかげた種類のプロパティです。.Net では、プロパティの自動バッキング フィールドが許可されるようになりました。public フィールドを使用する正当な理由はもうありません。

于 2012-08-08T23:05:26.867 に答える
0

あなたが持っているなら、Public Int MyAge 私はそれを-200または20,000に設定することができます、そしてあなたがそれについてすることができることは何もありません。

プロパティを使用する場合、たとえば、年齢が0〜150であることを確認できます。

編集:IanNortonの例によると(男、それは速かった)

于 2012-08-08T22:59:27.763 に答える