PropertyChanged bez przekazywania string’a

Często musimy implementować interfejs INotifyPropertyChanged. Szczególnie w przypadku wykorzystania wzorca MVVM oraz WPF. Najczęściej programiści wykorzystują podstawową implementację i przekazują nazwę parametru jako czysty string np:

if(PropertyChanged!=null)
{
    PropertyChanged(this,new PropertyChangedEventArgs("propName"));
}

Wszystko działa bardzo dobrze, dopóki nie zmienimy nazwy właściwości. Przede wszystkim należy wtedy pamiętać o zaktualizowaniu wszystkich wywołań ProperyChanged. Nie możemy ponadto skorzystać ze standardowego narzędzia do refaktoryzacji dostarczonego przez Visual Studio – string nie zostanie zmieniony. Istnieje jednak bardzo proste rozwiązanie, polegające na wykorzystaniu wyrażeń Lambda. Najlepiej rozważmy od razu fragment kodu:

public static class INotifyPropertyChangedExtensions
{
   public static void Raise<T>(this PropertyChangedEventHandler handler,object sender, Expression<Func<T>> expression)
   {
       if (handler != null)
       {
           var body = propertyExpression.Body as MemberExpression;
           if (body == null)
               throw new ArgumentException("'expression' should be a member expression");

           var expression = body.Expression as ConstantExpression;
           if (expression == null)
               throw new ArgumentException("'expression' body should be a constant expression");
   
           var e = new PropertyChangedEventArgs(body.Member.Name);
           handler(sender, e);
       }
   }      
}

Powyższa klasa to rozszerzenie do ProperyChangedEventHandler. Sprawdza ona czy jest podpięte jakieś zdarzenie, jeśli tak to odpala je przekazując dynamicznie skonstruowany PropertyChangedEventArgs. Teraz zamiast przekazywać nazwę właściwości w formie stringu, przekazujemy po prostu samą właściwość:

PropertyChanged.Raise(this,()=>this.Price);

6 thoughts on “PropertyChanged bez przekazywania string’a”

  1. @SheGe
    Dzieki za link. Faktycznie ciekawe. Lambda jest duza wolniejsza. Nie chce mi sie wiezyc w sumie, chyba sam przeprowadze taki test.

    Chociaz z drugiej strony, czy ma to jakiekolwiek znaczenie dla aplikacji biznesowej? Jakos nie chce mi sie wiezyc ze to faktycznie moze spowolnic dzialanie aplikacji.

  2. A tak nawiasem mówiąc to masz malutki błąd zamiast Expression<Func> expression
    powinno być
    Expression<Func> propertyExpression

Leave a Reply

Your email address will not be published.