typesafe NotifyPropertyChanged с использованием выражений linq - PullRequest
7 голосов
/ 26 апреля 2010

Форма Создайте свой собственный MVVM У меня есть следующий код, который позволяет нам совершать безопасные вызовы NotifyOfPropertyChange:

public void NotifyOfPropertyChange<TProperty>(Expression<Func<TProperty>> property)
{
    var lambda = (LambdaExpression)property;
    MemberExpression memberExpression;
    if (lambda.Body is UnaryExpression)
    {
        var unaryExpression = (UnaryExpression)lambda.Body;
        memberExpression = (MemberExpression)unaryExpression.Operand;
    }
    else memberExpression = (MemberExpression)lambda.Body;
    NotifyOfPropertyChange(memberExpression.Member.Name);
 }

Как этот подход сравнивается со стандартным подходом простых строк с точки зрения производительности? Иногда у меня есть свойства, которые меняются с очень высокой частотой. Могу ли я использовать этот безопасный подход? После первых тестов это, кажется, имеет небольшое значение. Какую нагрузку на процессор и память может вызывать этот подход?

Ответы [ 6 ]

5 голосов
/ 26 апреля 2010

Как выглядит код, который вызывает это? Я догадываюсь это что-то вроде:

NotifyOfPropertyChange(() => SomeVal);

что неявно:

NotifyOfPropertyChange(() => this.SomeVal);

, который делает захват this, и в значительной степени означает, что дерево выражений должно быть построено (с Expression.Constant) каждый раз с нуля. А потом разбираешь это каждый раз. Таким образом, накладные расходы определенно нетривиальны.

Не слишком ли слишком много ? Это вопрос, на который вы можете ответить только с профилированием и знанием вашего приложения. Он считается нормальным для большого количества использования MVC, но это (вообще) не вызывает его в длительном замкнутом цикле. Вам нужно выполнить профилирование в соответствии с желаемой целью производительности, в основном.

2 голосов
/ 27 июля 2010

У Эмиеля Джонгериуса хорошее сравнение производительности различных реализаций INotifyPropertyChanged.

http://www.pochet.net/blog/2010/06/25/inotifypropertychanged-implementations-an-overview/

Суть в том, что если вы используете INotifyPropertyChanged для привязки данных в пользовательском интерфейсе, то различия в производительности разных версий незначительны.

1 голос
/ 12 октября 2012

Как насчет использования стандарта defacto

if (propName == value) return;
propName = value;
OnPropertyChanged("PropName");

, а затем создайте пользовательский инструмент, который проверяет и изменяет код файла в соответствии с этим стандартом Этот инструмент может быть заданием перед сборкой, также на сервере сборки. Просто, надежно, выполняет.

0 голосов
/ 29 ноября 2012

Безопасность типов и отсутствие потери производительности: расширение NotifyPropertyWeaver. Он автоматически добавляет все уведомления перед компиляцией ...

0 голосов
/ 30 августа 2012

Я использую следующий метод в базовом классе, реализующем 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);
    }

Надеюсь, вы тоже найдете это полезным. : -)

0 голосов
/ 26 марта 2011

Прогулка по стеку идет медленно, а лямбда-выражение еще медленнее. У нас есть решение, похожее на хорошо известное лямбда-выражение, но почти такое же быстрое, как строковый литерал. Увидеть http://zamboch.blogspot.com/2011/03/raising-property-changed-fast-and-safe.html

...