プロパティの名前を変更し、INotifyPropertyChangedのPropertyChangedイベントのプロパティ名を除いて、Visual Studioの名前変更機能が必要なすべての名前変更を処理することが予期されるイベントです。あなたはそれを手動で名前を変更することを覚えておく必要はありませんので、何とか強く型付けされて取得するための良い方法はありますか?C#でPropertyChangedイベントを行うための強く型付けされた方法はありますか?
答えて
編集:nameof
がC#6に到着しました。
にはnameof
/infoof
などありません。これは多く議論されていますが、それはそれです。
.NET 3.5でラムダ式を使用して(そして式ツリーを解析する)方法がありますが、実際にはオーバーヘッドの価値はありません。今のところ、私は弦(とあなたがそれを壊さないことを決定した場合単体テスト)に固執します。
using System;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Reflection;
class Program : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
static void Main() {
var p = new Program();
p.PropertyChanged += (s, a) => Console.WriteLine(a.PropertyName);
p.Name = "abc";
}
protected void OnPropertyChanged<T>(Expression<Func<Program, T>> property) {
MemberExpression me = property.Body as MemberExpression;
if (me == null || me.Expression != property.Parameters[0]
|| me.Member.MemberType != MemberTypes.Property) {
throw new InvalidOperationException(
"Now tell me about the property");
}
var handler = PropertyChanged;
if (handler != null) handler(this,
new PropertyChangedEventArgs(me.Member.Name));
}
string name;
public string Name {
get{return name;}
set {
name = value;
OnPropertyChanged(p=>p.Name);
}
}
}
あなたの質問には答えられませんが、右クリック - >リファクタリング - >プロパティの名前を変更すると、プロパティ名に一致する文字列も含めて一致する文字列の名前を変更できます。
ええ、それは少し危険です。
コメントの名前を変更することは危険です。私は、この機能が名前を変更するコード要素のコメントにスコープを制限すると仮定して、むしろ大規模なプロジェクトでXML文書の束を混乱させました。 – snarf
PropertyChangedEventArgsは、プロパティ名を文字列として必要とするコンストラクタを1つだけ使用します。つまり、INotifyPropertyChangedを本質的に利用しないということは、あるレベルではアーキテクチャーの高低にかかわらず、文字列と手動で名前を変更する必要があります。
最も簡単な解決策は、スタックトレースを見て、completlyプロパティへのすべての明示的な参照を削除することです。 set_<PropertyName>
という名前のプロパティのセッターメソッドである -
public String Name
{
get { return this.name; }
set
{
if (value != this.name)
{
this.RaisePropertyChanging();
this.name = value;
this.RaisePropertyChanged();
}
}
}
private String name = null;
private void RaisePropertyChanged()
{
String propertyName =
new StackTrace().GetFrame(1).GetMethod().Name.SubString(4);
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(new PropertyChangedEventArgs(propertyName));
}
}
コードがcaling方法からスタックトレースを通じてプロパティ名を導出します。コンパイラがこの命名規則に従わなくなった場合、コードが破損します。
もう1つの解決策は、ラムダ式からプロパティ名を派生させることです。例
GetPropertyNameFromLambdaExpression<String, Int32>(s => s.Length)
については
public static String GetPropertyNameFromLambdaExpression<TObject, TProperty>(
Expression<Func<TObject, TProperty>> expression)
{
return ((MemberExpression)expression.Body).Member.Name;
}
exspectedとして "Length
" を返します。本番版のコードは、実際には追加のチェックとコードの残りの部分への統合が必要です。たとえば、汎用引数の型推論を使用することができます。
UPDATE
そして第三に解決策があります - あなたは、セッターやゲッターメソッドの名前を取得するプロパティのゲッターやセッターの内側MethodBase.GetCurrentMethod()
を使用することができます。
public String Name
{
get { return this.name; }
set
{
if (value != this.name)
{
String propertyName = MethodBase.GetCurentMethod().Name.SubString(4);
this.RaisePropertyChanging(propertyName);
this.name = value;
this.RaisePropertyChanged(propertyName);
}
}
}
private String name = null;
この解決方法は、単にプロパティ名を文字列として設定するよりも脆弱です。 – Charlie
これは面白そうです。ドキュメントをチェックせずに、私はSubStringへの呼び出しが何であるかを理解することはできません。 GetMethod()。Nameは何か奇妙なものを返しますか? –
プロパティは2つのメソッドによって実装されます。 public MyType MyProperty {get;セット; }は、public void set_MyProperty(MyType value){}およびpublic MyType get_MyProperty()として実装されています。したがって、返されたメソッド名からset_とget_を削除して、プロパティの名前を取得する必要があります。 –
理論上、プロパティセッター内では、MethodBase.GetCurrentMethod()。Name.Substring(4)を使用できます。残念ながら、Google検索ではit seems to have a significant performance impactと表示されます。考慮すべきもう2つの事項:
- JITインライン化は、予期しない方法でこれに影響を与える可能性があります。理論的には、MethodBase.GetCurrentMethod()へのIL呼び出しを簡単に置き換えることができました(理論的には、MethodBase.GetCurrentMethod実行時にJITによってldtoken命令とそれに続くMethodBase.GetMethodFromHandle()への呼び出しがあり、非常に高速です。私はユーザーがちょうどこれの必要性を表明していないと思います。 (msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ldtoken.aspx)
- 完全に私の意見はここですが、fieldof()とmethodof() C#の演算子。その能力を必要とするプロジェクトでコード分析/リファクタリングツールの信頼性を大幅に向上させると私は信じています。
あなたはblog postをチェックアウトする必要があります。
string propertyName = TypeHelper.GetPropertyName<User>(u => u.LastProjectCode);
PropertyInfo property1 = TypeHelper.GetProperty((SomeClass o) => o.InstanceProperty.Length);
PropertyInfo property2 = TypeHelper.GetProperty(() => SomeClass.StaticProperty.Length);
Visual Studio/Resharper/Refactor Proの名前を変更する必要があります。
C#5には解決策があるようです。パラメータOne example on the netで使用できるCallerMemberName
attributeがあります。
class Employee : INotifyPropertyChanged
{
private string _Name;
public string Name
{
get { return _Name; }
set
{
_Name = value;
RaisePropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged([CallerMemberName] string caller = "")
{
var temp = PropertyChanged;
if (temp != null)
{
temp(this, new PropertyChangedEventArgs(caller));
}
}
}
うわー!あなたのものは一番クールだそうです。 – VivekDev
- 1. MongoDBドライバC#強く型付けされたネストされたインデックス
- 2. 強く型付けされたカスタムヘルパーメソッドを作る方法は?
- 3. MVCアプリケーションで強く型付けされたビューで特定の行のデータを取得する方法..? (クラス名と強く型付けされたビュー:BusDetails.cs)
- 4. C#MongoDBドライバは強く型付けされたフィルタの使用
- 5. 強く型付けされたURLアクション
- 6. 強く型付けされたRadioButtonlist
- 7. 強く型付けされたList.GroupBy()
- 8. 強く型付けされたフィールドをループするEntity Framework c#
- 9. 強く型付けされたデータセットでは、テーブルのマッピングに問題はありませんか? C#.net 2.0
- 10. バルク更新は強く型付けされたデータセットですか?
- 11. 強く型付けされたWebFormsをMVC Viewsに似せる方法はありますか?
- 12. 強く型付けされたenumのC++変換
- 13. 強く型付けされたパラメータにC#の名前?
- 14. 強く型付けされたクライアント側の言語ですか?
- 15. 強く型付けされたASP.NET MVCセッションのより良い方法
- 16. ネストされた配列プロパティのMongo C#強く型付けされたインデックス
- 17. 強く型付けされたイベントの定義を追加する
- 18. XMLで強く型付けされたプリミティブ値を要求する方法
- 19. 強く型付けされたtableAdapterをフォームで指定する方法
- 20. 強く型付けされたビューはいつ使うべきですか?
- 21. 本当に強く型付けされた型のプロバイダ
- 22. mongoDB、C#の公式ドライバを使った強く型付けされたコレクション
- 23. コントローラで強く型付けされたモデルの "キー"を取得
- 24. 動的型と強く型付けされた要素
- 25. 強く型付けされた言語の違いは?
- 26. `ActionExecutingContext`から強く型付けされたコントローラを入手できますか?
- 27. は、モデルパラメータは、強く型付けされたコンテナモデル
- 28. 強く型付けされた部分図にモデルを渡す方法
- 29. ASP.Net MVC複数のモデルで強く型付けされたビュー
- 30. 強い型付けされたコンテナ
(リクエスト/コメントごとに追加された例) –
この記事をご覧ください。 http://weblogs.asp.net/dwahlin/archive/2009/07/07/validating-properties-in-silverlight-classes.aspx INotifyPropertyChangedを実装し、それから派生する基本クラスを作成する場合は、多分、これを使うことができます。 –
INotifyPropertyChangedを実装するコンパイラがチェックした方法については、http://stackoverflow.com/questions/1329138/how-to-make-databinding-type-safe-and-support-refactoring/1333874#1333874を参照してください。プロパティ名が魔法の文字列であるのを避ける。 –