Bastien Vandamme
Bastien Vandamme

Reputation: 18465

How to write MVVM properties?

With MVVM I always see these both methods for properties:

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

and

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

The first one use an hardcoded string to NotifyPropertyChanged and the second one use a lambda expression to NotifyPropertyChanged. I don't want to create a debate to ask what is the better solution but I would like to understand what are the differences bewteeen these two solution. What are the consequences of using one or the other?

Correct me if I'm wrong but the lambda expression solution should use more memory and should be slower than the hardcoded string because the NotifyPropertyChanged method of the base class use delegate and reflection. But the hardcoded string solution may create stupid bug because it's a string and nothing to tell me I correctly wrote it.

Upvotes: 1

Views: 205

Answers (3)

Joben Blom
Joben Blom

Reputation: 31

I use the following method in a base class implementing INotifyPropertyChanged and it is so easy and convenient:

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);
    }

Upvotes: 0

Moble Joseph
Moble Joseph

Reputation: 657

Rather than repeating that code of NotifyPropertyChanged for every property, I felt the below code is more cleaner

Create a Set method in your ViewModel Base

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;
}

and use them as

string title;
public string Title
{
   get { return title; }
   set { Set(() => Title, ref title, value); }
}

Upvotes: 1

Adam Houldsworth
Adam Houldsworth

Reputation: 64487

The second expression would either generate a compiler error on the property name change, or would automatically change with it (via the Rename support in VS or ReSharper).

So basically, you gain compiler support for property names. The wrong name provided to the notify would mean that data-binding would break. With string names, this breakage would be silent.

In a small UI the choice is irrelevant in my opinion, but in a large application with a heavy UI layer the extra support against bugs can pay itself off in the long run.

Performance won't be problematically slower, don't forget, binding is reflection-powered anyway. Performance, as always, is relative. The hard-coded version will technically be faster because it doesn't need to reflect the property name out of the meta-data. How much faster, I'm not sure.

Upvotes: 3

Related Questions