The Magic of CallerMemberName

Oh my goodness. The things you find when you are searching for something else. While I was looking up some stuff on Model View View Model I came across a C# feature I've not seen before. It's called [CallerMemberName] and it is awesome. It has some  useful siblings too, which I'll get to in a moment. I'm dashing off a quick blog post about it now so that I can tell everyone, and also so I can remind myself how it works in the future.

CallerMemberName lives in the System.Runtime.CompilerServices namespace and it has one simple behaviour. It lets a method know the method or property it was called from. You use it as a parameter to the method, like so:

void Demo([CallerMemberName] string name = "")
{
    Console.WriteLine(name);
}

The method Demo has a single parameter which is called name. All it does is print the name out. The parameter has a default value of "" and the strange [CallerMemberName] attribute thingy in front of it. When the method runs it prints the contents of  name. So, if we make a call to Demo from within another method - like this:

public void DoSomething()
{
    Demo();
}

- the program would print "DoSomething", because that is the name of the method that called Demo. It gets better. I can also do things like this:

private int aProperty = 0;

public int AProperty
{
    get
    {
        return aProperty;
    }
    set
    {
        Demo();
        aProperty = value;
    }
}

This time I'm calling Demo from within AProperty. And it prints "AProperty".  So far, so good.  Might be fun for code instrumentation. But why do I like it so much?

Answer, if you've not figured it out already, is that one of the more painful things about creating ViewModel classes for your applications is that when you set a property you have to call a method to tell the system that the value of that particular property has changed. And you have to give the method call the name of the property that has changed. As a string. If you get the name wrong (it has been known) a whole heap of nothing happens and your display is not updated properly. If you've done any MVVM in C# you'll be nodding around now.

If we use [CallerMemberName] we can get the name of the property being updated straight from the property itself, which means that we can make a generic notifier method that works for all the properties in the ViewModel class. No more errors caused by mistyping. There's a nice description of that part here

There are a couple of other "Caller" features you can use that work in exactly the same way, and might be fun to play with:

[CallerFilePath]
[CallerLineNumber]

They are fairly self-explanatory. 

Great fun.