1

MVVMを使用すると、プロパティに対して次の両方の方法が常に表示されます。

    private int myProperty;
    public int MyProperty
    {
        get { return myProperty; }
        set
        {
            myProperty = value;
            NotifyPropertyChanged("MyProperty");
        }
    }

    private int myProperty;
    public int MyProperty
    {
        get { return myProperty; }
        set
        {
            myProperty = value;
            NotifyPropertyChanged(m => m.MyProperty);
        }
    }

1つ目はハードコードされた文字列を使用してNotifyPropertyChangedを使用し、2つ目はラムダ式を使用してNotifyPropertyChangedを使用します。どちらがより良い解決策であるかを尋ねる議論をしたくはありませんが、これら2つの解決策の違いは何であるかを理解したいと思います。どちらか一方を使用するとどうなりますか?

私が間違っている場合は訂正してください。ただし、基本クラスのNotifyPropertyChangedメソッドはデリゲートとリフレクションを使用するため、ラムダ式ソリューションはより多くのメモリを使用し、ハードコードされた文字列よりも低速である必要があります。しかし、ハードコードされた文字列ソリューションは、文字列であり、正しく記述したことを私に伝えるものがないため、ばかげたバグを作成する可能性があります。

4

3 に答える 3

3

2番目の式は、プロパティ名の変更時にコンパイラエラーを生成するか、(VSまたはReSharperの名前変更サポートを介して)自動的に変更されます。

したがって、基本的には、プロパティ名のコンパイラサポートを取得します。通知に間違った名前が指定されていると、データバインディングが壊れることを意味します。文字列名を使用すると、この破損は発生しません。

私の意見では、小さなUIでは選択は重要ではありませんが、UIレイヤーが重い大規模なアプリケーションでは、バグに対する追加のサポートが長期的に見返りをもたらす可能性があります。

パフォーマンスが問題なく遅くなることはありません。とにかくバインディングはリフレクションを利用していることを忘れないでください。いつものように、パフォーマンスは相対的です。ハードコーディングされたバージョンは、メタデータからプロパティ名を反映する必要がないため、技術的に高速になります。どれだけ速いかはわかりません。

于 2012-07-17T12:35:12.963 に答える
1

すべてのプロパティに対してNotifyPropertyChangedのコードを繰り返すのではなく、以下のコードの方がクリーンだと感じました。

ViewModelベースにSetメソッドを作成します

protected bool Set<T>(Expression<Func<T>> selectorExpression, ref T field, T value)
{
    if (EqualityComparer<T>.Default.Equals(field, value))
       return false;
    field = value;
    RaisePropertyChanged(selectorExpression);
    return true;
}

そしてそれらをとして使用します

string title;
public string Title
{
   get { return title; }
   set { Set(() => Title, ref title, value); }
}
于 2012-07-17T13:05:00.300 に答える
0

INotifyPropertyChangedを実装する基本クラスで次のメソッドを使用します。これはとても簡単で便利です。

public void NotifyPropertyChanged()
    {
        StackTrace stackTrace = new StackTrace();

        MethodBase method = stackTrace.GetFrame(1).GetMethod();

        if (!(method.Name.StartsWith("get_") || method.Name.StartsWith("set_")))
        {
            throw new InvalidOperationException("The NotifyPropertyChanged() method can only be used from inside a property");
        }

        string propertyName = method.Name.Substring(4);

        RaisePropertyChanged(propertyName);
    }
于 2012-08-30T01:05:04.407 に答える