2009-09-15 20 views
12

変更イベントを発生させたままで、自動実装されたプロパティを引き続き使用する方法はありますか?たとえば、INotifyPropertyChanged代わりのC#で自動実装されるプロパティ

private string _value; 
public string Value 
{ 
    get 
    { 
    return this._value; 
    } 
    set 
    { 
    this._value = value; 
    this.ValueChanged(this,EventArgs.Empty); 
    } 
} 

私はちょうど行うことができます:セッターが間違って見える

public string Value 
{ 
    get; 
    set 
    { 
    this.ValueChanged(this,EventArgs.Empty); 
    } 
} 

が、バッキングストア変数で私のクラスを充填せずにこれを行うことが可能ですか?

更新:私の怠惰な目的には標準的な解決策がないように見えますが、私はCodeRushまたはResharperを使用して私のバッキングストアをすべて生成することをお勧めします。

答えて

6

あなたがこれを行うことはできません。自動的に実装プロパティの仕様はかなり明確です:

自動的に実装 (自動実装)プロパティが このパターンを自動化します。具体的には、 抽象的なプロパティ宣言は、 セミコロンのアクセサーを持つことができます ボディです。両方のアクセサが存在する必要があります。 セミコロン本体は、 である必要がありますが、異なるアクセシビリティ修飾子を持つ可能性があります( )。このように プロパティが指定されている場合、 バッキングフィールドは自動的に になり、 アクセサが実装され、 がそのバッキングフィールドとの間で読み書きされます。 バッキングフィールドの名前は コンパイラが生成されており、ユーザは にアクセスできません。言い換えれば

、彼らは唯一のアクセス修飾子の可能性と、「get;」と「」を持つことができます。

4

ありませんあなたは、することはできませんあなたがそのプロパティに対して

4

を生成した秘密フィールドへのアクセスを持っていないので、「INotifyPropertyChangedの自動プロパティ」のクイックGoogle検索は、上のいくつかのブログの投稿や記事にあなたを導きます主題ここでは一つだ:

INotifyPropertyChanged auto wiring or how to get rid of redundant code

+0

私はこれが動作することを確認することができますが、それは実際にバッキングストアの変数を使用するよりも乱雑に見える – benPearce

+0

benPearce:自動プロパティは、あなたがしたくないときのためにありますsetterまたはgetterに他のコードを記述します。あなたが(プロパティの変更の通知のように)行う場合は、それを記述する必要があります。 PostSharpのアプローチには同意しませんが、確かにソートの解決策です。変数を手作業で書き出すコードはとても快適です。 –

+0

シルキー:私はPostsharpであなたに同意しますが、それは特に私がそれに熱心ではない解決策です。 – benPearce

1

これはC#3.0の背後にあるマイクロソフトのチームに尋ねられました。彼らはそれについて考えると、hereと書いてあります。

コメントには、さらに制御が必要な場合やそれを達成する方法が悪い理由など、詳細情報が記載されています。

1

PostSharpのようなAOPフレームワークを使用できます。

しかし、パフォーマンスとビルド時間を短縮できます。

+0

Postsharp 2.0がまさにこれをしているように見える - http://www.postsharp.org/blog/introducing-postsharp-20-1-notifypropertychanged – benPearce

0

この動作は、プロキシファクトリタイプのジェネレータを使用して行うことができます。私はすでに開発フレームワークでそれを行っています。 System.Reflection.Emitを使用すると、タイプのプロキシーを作成できます。 例の下に考えてみましょう:アドインPropertyChangedこれを行い https://github.com/demigor/kindofmagic

1

私はこの問題は、実際の属性として解くと、タスクを構築してきたこの質問をしたので。 KindOfMagicのように、FodyはMono.Cecilを使用して、コンパイル時に.NetアセンブリのILを変更します。次の例は、のPropertyChangedドキュメントに記載されて:

あなたが書く

コンパイルされる何

[ImplementPropertyChanged] 
public class Person 
{   
    public string GivenNames { get; set; } 
    public string FamilyName { get; set; } 

    public string FullName 
    { 
     get 
     { 
      return string.Format("{0} {1}", GivenNames, FamilyName); 
     } 
    } 
} 

public class Person : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    string givenNames; 
    public string GivenNames 
    { 
     get { return givenNames; } 
     set 
     { 
      if (value != givenNames) 
      { 
       givenNames = value; 
       OnPropertyChanged("GivenNames"); 
       OnPropertyChanged("FullName"); 
      } 
     } 
    } 

    string familyName; 
    public string FamilyName 
    { 
     get { return familyName; } 
     set 
     { 
      if (value != familyName) 
      { 
       familyName = value; 
       OnPropertyChanged("FamilyName"); 
       OnPropertyChanged("FullName"); 
      } 
     } 
    } 

    public string FullName 
    { 
     get 
     { 
      return string.Format("{0} {1}", GivenNames, FamilyName); 
     } 
    } 

    public virtual void OnPropertyChanged(string propertyName) 
    { 
     var propertyChanged = PropertyChanged; 
     if (propertyChanged != null) 
     { 
      propertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

wikiは、いくつかのより高度な例が含まれています。

それはNuGetを使用して提供されています:

PM> Install-Package PropertyChanged.Fody 
0

Fody:

var a = Proxier<InputType>.CreateInstance(new object[] { }); // object arrays are for different constructors 
a.PropertyAccessed += ... 
関連する問題