2012-04-20 10 views
0

#define str(s) #sマクロを使用してC言語のように.NET 4.0のメンバー名をC#で文字列化する方法はありますか?c#.NETで#define str(s)#s in Cに類似した文字列

public Double MyDouble 
{ 
    get { return _MyDouble;} 
    set 
    { 
     _MyDouble = value; 
     RaisePropertyChanged("MyDouble"); 
     // The below item would refactor correctly if C# had a stringify pre-processor 
     // RaisePropertyChanged(str(MyDouble)); 
    } 
} 
private Double _MyDouble; 

再因数分解が有効になっている場合、私はSearch in Strings無効または破損全く関係のない文字列を持っている場合はレイズプロパティ変更イベントを壊します。 UI要素が変更に応答しなくなるまで気付かないことがあります。

答えて

6

いいえ、残念ですが、現在、PostSharpやNotifyPropertyWeaverのようなものを使って、これを確実に行う必要があります。

C#5でこれを行うことができるようになりますことをご注意:

public void RaisePropertyChanged([CallerMemberName] string member = "") 
{ 
} 

だからよう、あなたはそれを使用します。

public Double MyDouble 
{ 
    get { return _MyDouble;} 
    set 
    { 
     _MyDouble = value; 
     RaisePropertyChanged(); 
    } 
} 

そして、C#5コンパイラが自動的に入力されますオプションのパラメータ

あなたができる最善のは、(明らかに理想的ではないが)、以下れる OnPropertyChangedのあなたの特定のケースについては
+0

C#4.0では、リフレクションを使用してメンバー名を取得するなどの方法がありますか? – NtscCobalt

+1

@NtscCobalt私はNotifyPropertyWeaverに行くだろう。 Reflectionを使用して何かを取り除くことができるかもしれませんが、JITは物事をインライン化できるので、結果は保証されません。 Plusプロパティはメソッドのための派手なアクセサであり、再びスタックを醜く歩いてしまいます。 – vcsjones

2

...

this.OnPropertyChanged(x => x.Member); 

...と...

protected void OnPropertyChanged(Expression<Func<T, object>> property) 
{ 
    var propertyName = GetPropertyName(property.Body); 
    if (this.PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
} 
private static string GetPropertyName(Expression expression) 
{ 
    switch (expression.NodeType) 
    { 
     case ExpressionType.MemberAccess: 
      var memberExpression = (MemberExpression)expression; 
      var supername = GetPropertyName(memberExpression.Expression); 

      if (String.IsNullOrEmpty(supername)) 
       return memberExpression.Member.Name; 

      return String.Concat(supername, '.', memberExpression.Member.Name); 

     case ExpressionType.Call: 
      var callExpression = (MethodCallExpression)expression; 
      return callExpression.Method.Name; 

     case ExpressionType.Convert: 
      var unaryExpression = (UnaryExpression)expression; 
      return GetPropertyName(unaryExpression.Operand); 

     case ExpressionType.Parameter: 
      return String.Empty; 

     default: 
      throw new ArgumentException(); 
    } 
} 

..これらの行に沿って...

+0

このコードにはもう少しの文脈が必要です。 'T 'はどこから来たの? – vcsjones

+0

彼は 'protected void OnPropertyChanged (式>プロパティ)'を意味すると思います。これは非常に面白い方法ですが、実際には効率的ではありません。なぜなら、表現に関してはafaikなので、コンパイル時には解析できず、知られていないからです。 – NtscCobalt

+0

@vcsjonesこれは基本的にこの 'protected void OnPropertyChanged(Expression <)を呼び出すことで、' this.OnPropertyChanged(x => x.ExpressionText); ' Func >プロパティ) '。それは推定されるところです - 'T'はあなたのビューモデルクラスですが、オブジェクトはプロパティ型です(私たちができるすべてのオブジェクト)。 – NSGaga

関連する問題