私は、ラムダ式への切り替えの影響を確立するためNotifyPropertyChangedの徹底的なテストを行いました。
ここにいた私のテスト結果:
![enter image description here](https://i.stack.imgur.com/idHSO.png)
あなたが見ることができるようには、ラムダ式を使用すると、プレーンハードコードされた文字列プロパティの変更の実装よりも約5倍遅くなりますが、ユーザーは心配してはいけませんなぜなら、それでもそれほど特別な作業コンピュータでは毎秒十万回のプロパティ変更をポンピングできるからです。このように、文字列をハードコードする必要がなくなり、すべてのビジネスを世話するワン・ライン・セッターが私にとってパフォーマンス・コストをはるかに上回ることから得られる利点が得られます。
試験1プロパティが実際に変化したことを確認してくださいと、標準的なセッターの実装を使用する:
public UInt64 TestValue1
{
get { return testValue1; }
set
{
if (value != testValue1)
{
testValue1 = value;
InvokePropertyChanged("TestValue1");
}
}
}
試験2イベントを可能にする機能を加えて、非常に類似していました古い値と新しい値を追跡します。この機能は私の新しいベースセッターメソッドで暗黙的になる予定だったので、私はその機能によるものであったどのくらいの新しいオーバーヘッドの見たかった:ゴムが道路を満たしている
public UInt64 TestValue2
{
get { return testValue2; }
set
{
if (value != testValue2)
{
UInt64 temp = testValue2;
testValue2 = value;
InvokePropertyChanged("TestValue2", temp, testValue2);
}
}
}
テスト3であったが、私BindingObjectBaで
public UInt64 TestValue3
{
get { return testValue3; }
set { SetNotifyingProperty(() => TestValue3, ref testValue3, value); }
}
実装
:と私は1つのライン内のすべての観測可能なプロパティのアクションを実行するため、この新しい美しい構文を披露してもらいますすべてのViewModelが継承するseクラスは、新しい機能を実現する実装にあります。私は明確なので、関数の肉をエラー処理をされて取り除かました:
protected void SetNotifyingProperty<T>(Expression<Func<T>> expression, ref T field, T value)
{
if (field == null || !field.Equals(value))
{
T oldValue = field;
field = value;
OnPropertyChanged(this, new PropertyChangedExtendedEventArgs<T>(GetPropertyName(expression), oldValue, value));
}
}
protected string GetPropertyName<T>(Expression<Func<T>> expression)
{
MemberExpression memberExpression = (MemberExpression)expression.Body;
return memberExpression.Member.Name;
}
すべての3つの方法がまだ標準であるOnPropertyChangedをルーチン、で会う:
public virtual void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(sender, e);
}
ボーナス
誰かが興味があれば、PropertyChangedExtendedEventArgsは標準のPropertyChangedEventArgsを拡張するために出てきたものなので、拡張のインスタンスは常にベースの代わりになります。これは、プロパティがSetNotifyingPropertyを使用して変更されたときに古い値の知識を活用し、この情報をハンドラが利用できるようにします。
public class PropertyChangedExtendedEventArgs<T> : PropertyChangedEventArgs
{
public virtual T OldValue { get; private set; }
public virtual T NewValue { get; private set; }
public PropertyChangedExtendedEventArgs(string propertyName, T oldValue, T newValue)
: base(propertyName)
{
OldValue = oldValue;
NewValue = newValue;
}
}
私はこれを反映しています。私のブログ記事はこちらをご覧ください。 [http://tsells.wordpress.com/2011/02/08/using-reflection-with-wpf-and-the-inotifypropertychanged-interface/](http://tsells.wordpress.com/2011/02/08)/use-reflection-with-wpf-and-inotifypropertychanged-interface /)投稿の最後に掲載されているパフォーマンスノートに注意してください。 – tsells
良い記事ですが、パフォーマンスの時間に絶対的な違いがありますが、それは有用ではありません。私は、パフォーマンス時間のパーセンテージの違いにもっと興味を持っています。 200ミリ秒から300ミリ秒、そして0.01ミリ秒から100.01ミリ秒の間には大きな違いがあります。同じ絶対差、異なるパーセント差。 – Alain
彼は10,000のプロパティ変更通知で約1/4秒の差があると述べました。私はそれが気にする十分大きな違いだとは思っていません。もしあなたが本当に一度に10kのプロパティを更新しているなら、私は真剣にデザインを再考します:) – Rachel