10

I was reading about the new nameof keyword in C# 6. I want to know how can I implement INotifyPropertyChanged using this keyword, what are the prerequisites (of course other than C# 6) and how it will effect the performance of my MVVM application?

3
  • 1
    There are already alternatives to the magic string problem, just so you know. Though nameof should formalise that. Commented Dec 12, 2014 at 11:18
  • 1
    No, I never pointed that out. I was merely informing you just in case you were waiting for something that is not yet released to solve something that you could solve today. It is also useful for other visitors as this question is not solely for your benefit. Commented Dec 12, 2014 at 11:22
  • Useful RegEx to replace all in Visual Studio: from OnPropertyChanged("(?<propName>\w+)"\); to OnPropertyChanged(nameof(${propName})); Commented May 3, 2021 at 8:13

5 Answers 5

14

It would look like this:

public string Foo
{
   get
   {
      return this.foo;
   }
   set
   {
       if (value != this.foo)
       {
          this.foo = value;
          OnPropertyChanged(nameof(Foo));
       }
   }
}

The nameof(Foo) will be substituted with the "Foo" string at compile time, so it should be very performant. This is not reflection.

Sign up to request clarification or add additional context in comments.

5 Comments

Which ironically is more code than the other mechanism that uses CallerMemberName, and unfortunately is not as comical as infoof.
CallerMemberName is only available in .NET 4.5. Nameof comes with the C# compiler so you'll still be able to target older .NET frameworks.
True, hadn't thought of that benefit. But interestingly, CallerMemberName is also a compiler-powered feature so can be taken out of the .NET 4.5 dependency. I would personally change to nameof for the other reason that the code is more explicit and less is hidden from the caller's perspective.
I suppose nameof(Foo) is enough since the property is certainly in scope. If you want to qualify for some reason, isn't nameof(this.Foo) better than nameof(MyClass.Foo) for a non-static member? I have not tried to actually compile any of this.
I still believe that [CallerMemberName] has the advantage simply because nameof doesn't solve the pedanticity (?) problem, i.e. you still have to write the enclosing property's name manually in each property. At that point you might as well just type a magic string there. Whereas [CallerMemberName] is less human-error-prone because you write the same line of code in each and the compiler takes care of getting the correct property name.
6

It's just a matter of using nameof() instead of the magic string. The example below is from my blog article on the subject:

private string currentTime;

public string CurrentTime
{
    get
    {
        return this.currentTime;
    }
    set
    {
        this.currentTime = value;
        this.OnPropertyChanged(nameof(CurrentTime));
    }
}

Since it is evaluated at compile-time, it is more performant than any of the current alternatives (which are also mentioned in the blog article).

1 Comment

Thanks for the answer. I really liked your blog entry
4

Here's a complete code sample of a class using the new C# 6.0 sugar:

public class ServerViewModel : INotifyPropertyChanged {
    private string _server;
    public string Server {
        get { return _server; }
        set {
            _server = value;
            OnPropertyChanged(nameof(Server));
        }
    }

    private int _port;
    public int Port {
        get { return _port; }
        set {
            _port = value;
            OnPropertyChanged(nameof(Port));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName) => 
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

With this, you get the nameof() operator, the null-conditional operator ?., and an expression-bodied function (the OnPropertyChanged definition).

Comments

3

I've found it's a lot easier to use PropertyChanged.Fody as you end up with less mistakes and a hell of a lot cleaner code, see - https://github.com/Fody/PropertyChanged

All you have to do is label up your class with ImplementPropertyChanged attribute:

[ImplementPropertyChanged]
public class Person 
{        
    public string GivenNames { get; set; }
    public string FamilyName { get; set; }

    public string FullName
    {
        get
        {
            return string.Format("{0} {1}", GivenNames, FamilyName);
        }
    }
}

And after build it gets transformed in to:

public class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    string givenNames;
    public string GivenNames
    {
        get { return givenNames; }
        set
        {
            if (value != givenNames)
            {
                givenNames = value;
                OnPropertyChanged("GivenNames");
                OnPropertyChanged("FullName");
            }
        }
    }

    string familyName;
    public string FamilyName
    {
        get { return familyName; }
        set
        {
            if (value != familyName)
            {
                familyName = value;
                OnPropertyChanged("FamilyName");
                OnPropertyChanged("FullName");
            }
        }
    }

    public string FullName
    {
        get
        {
            return string.Format("{0} {1}", GivenNames, FamilyName);
        }
    }

    public virtual void OnPropertyChanged(string propertyName)
    {
        var propertyChanged = PropertyChanged;
        if (propertyChanged != null)
        {
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

3 Comments

Fantastic helper. I use a lot of POCOs for data interchange with ServiceStack, and this lets me keep them super-simple (code-wise).
This answer would be better if you included an explanation of what Fody is. Also, the transformed code still has magic strings in it, which is what the OP wants to avoid. If the name of one of the properties is changed, will Fody update the strings automatically too?
So fody is a post build il weaver so it changes your code after its built... The magic strings will get updated automatically after each build
1

See the documentation for INotifyPropertyChanged.PropertyChanged Event

private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.