自動実装されたプロパティはフィールドの使用を取り除きますか?

プロパティはパブリックとプライベートのgetter/setterを持つことができるので、フィールドはまだ使用されていますか?フィールドを使用して得られる動作は、コンパイラが使用する不可視変数を使用するようにプロパティのget/setブロックを設計し、フィールドをalltogetherのままにすることによって得られます。

0

5 答え

いいえ、自動実装された小道具は、背景フィールドの必要性を取り除いていません。場合によっては、プロパティgetter/setterがより多くの作業を行い、次に値を保持することがあります。フィールドが必要な場合が多くあります。非常に良い例は、バインディングのためにINotifyPropertyChangedを実装するときです。

そのようです:

class someClass : INotifyPropertyChanged
{
// details omitted.....

    private int _myInt
    public int myInt { get { return _myInt; }
                       set { if ( value == _myInt ) return;
                             _myInt = value;
                             RaiseNotify("myIng");
                           }}
}

これはフィールドを裏付けることなく不可能になります。

3
追加された
別の例:参照または出力( ref obj.fieldname および out obj.fieldname )でフィールドを渡すことはできますが、参照または出力でプロパティを渡すことはできません。
追加された 著者 Raymond Chen,
+1、 INPC は私の心にも来る最初のものです
追加された 著者 sll,

フィールドの値を取得してフィールドを設定することは可能ですが、フィールドではプロパティでは実行できないいくつかのことを行うことができます。

  1. It is possible to modify the value of a field in such a way that the new value will depend upon the old value at the exact moment of modification. This has different semantics from reading the property, computing a new value, and writing it back.
  2. It is possible to pass a field by reference to methods which are then free to perform whatever sequence of reads and writes they see fit, with such reads or writes happening "live". Again this has different semantics from passing a copy of the property to a method, receiving a modified copy back from the method, and storing that modified copy back to the original.

実際のフィールドを公開することなく 'フィールドのような'ことを可能にする方法でプロパティを公開したい場合は、以下のように宣言された汎用のUsePropertyメソッドのファミリを持つことができます。

delegate TResult; FuncRef(ref T1);
ResultType UseProperty
  (FuncRef func)
  {return func(_field);}
delegate TResult; FuncRef(ref T1 p1, ref T2 p2>
ResultType UseProperty
  (FuncRef func, ref T1 p1)
  {return func(_field, p1);}
delegate TResult; FuncRef(ref T1 p2, ref T2 p2, ref T3 p3>
ResultType UseProperty
  (FuncRef func, ref T1 p1, ref T2 p2)
  {return func(_field, p1, p2);}

残念ながら、C#またはvb(つまり、任意の数の 'ref'パラメータを受け入れ、呼び出されたコードで利用できるようにする '普遍的な'関数)でそのような関数のファミリを宣言する良い方法はありません。あまりにも悪いことに、言語サポートによっては、情報へのアクセスを制御するための非常に優れたパラダイムが提供される可能性があります(つまり、特定の情報を修正する準備をして一般的なコードで情報を修正し、新しいオブジェクトインスタンスを作成する必要はありません)。

0
追加された

人々が保護されたフィールドと公開されたフィールドにプロパティを使用する主な理由は、バイナリ互換性を損なうことなく動作を追加できることです。つまり、クラスを使用する(呼び出し、サブクラスなど)コードを再コンパイルする必要はありません。

動作のないプライベートメンバーのプロパティを使用する必要はありません。その場合、フィールドを使用することができます。後で動作を追加する(プロパティにする)必要がある場合は、とにかくそのクラスを再コンパイルします。

フィールドのパフォーマンスは向上します(ただし、使用しているJITのバージョンによって異なります)。理由がない限り使用する必要があります。

編集:

ちょうど混乱を避けるために:

フィールド:

private SomeType fieldName;

自動プロパティ:

private SomeType fieldName { get; set; }
0
追加された
@BlowedAway、私はフィールドとプロパティ(具体的には自動プロパティ)を比較しています。フィールドも1行にあり、短いです。
追加された 著者 Matthew Flaschen,
ああ、私は参照してください。感謝のほとんどを知りませんでした:)
追加された 著者 Blowed Away,
もちろん、それはすべてが1行にあるので、自動プロパティを使用する方が素早く、きれいです。私はそれの簡潔さが好きです。
追加された 著者 Blowed Away,

ほとんどの場合、フィールドの代わりにautogen getterとsetterを使用できますが、微妙な違いがあります。getterとsetterはインライン化されていても関数呼び出しであるため、バッキング変数は常にvolatileのように扱われます。

0
追加された

自動実装されたプロパティは、単純なケースではフィールドの必要性を排除します。

しかし、任意の種類のロジックや検証やイベントをプロパティセッターに追加する場合は、フィールドが必要です。

0
追加された