Four "Hello my name is" nametags with the words "CalculateAnswer", "ExportGridContents", "FetchExternalData", and "HideBody"

A number of years ago .NET added a small feature called Caller Member Info. This isn’t the biggest feature out there, and you’re not going to use this frequently unless you’re doing a lot of XAML development, but it’s good to have in your tool belt.

Caller Member Info attributes allow you to simplify your code by providing more information to individual methods without having to pass in explicit values.

In this short article I’ll give you an overview of the caller member info attributes, how they work, and the problems they can solve.

The Problem

Let’s say you have code that does some standard checks:

There’s some obvious code duplication here. We can clean it up by extracting a method:

Okay, cool. We now have logic in one method, but having to pass in the method name is a little irritating.

This is where CallerMemberNameAttribute comes into play. Let’s take a look at an improved version of the code and then discuss how it works:

Note here that the code is barely changed. We added [CallerMemberName] to the methodName parameter on CheckInput and also made methodName optional by giving it a default value of an empty string.

The optional parameter allows the code to compile, and then .NET inspects the CallerMemberName attribute at runtime and injects IL code to switch from the default value to that of the name of the method that just called the executing method.

For example, in DoBar(), CheckInput is called and the methodName parameter is not specified. Instead of taking the default value of "", the CallerMemberName attribute sets the value of methodName to DoBar, the caller.

How is this useful?

Admittedly it’s an interesting parlor trick for developer parties (I don’t know for sure, I don’t get invites to those), but how is this actually useful?

For one, logging methods can frequently benefit from knowing who called them.

For another, if you do work with model view view model frameworks (MVVM) such as XAML that rely on things like INotifyPropertyChanged, you frequently need to state the name of the property that changed. This allows our code to be very simple:

We also copy and paste code more than we’d like to admit – even small pieces of code. Why? Because we hate boilerplate and logging, validation, and property changed notifications are all boiler-plate things.

If we copy and paste and forget to change the name, mistype it, or we rename a method or property down the road without changing the string value, these all can lead to bugs and confusion. Admittedly, the nameof keyword can help with the renaming scenario, but the point remains: Code you don’t have to write won’t break.

This is a point I’m quite fond of making, but it’s true. If you don’t have to code something, you won’t make a mistake doing it.

Other Caller Member Info Attributes

Okay, so we talked at length at how CallerMemberName gets us the name of the method or property that invoked the method.

Beyond that, we also have the CallerLineNumberAttribute and CallerFilePathAttribute. Both work similarly to CallerMemberNameAttribute(though CallerLineNumber works with an integer) and will provide orienting information on the source code as it existed at compile time.

Realistically you won’t use these nearly as much as CallerMemberName. The only reason I’ve needed either of these two attributes has been around error logging code.


If you’d like to read more, check out Microsoft’s documentation on Caller Member Info.

If you do use any of these attributes for something I haven’t mentioned, I’d love to hear about it. Please send me a note in the comments or on twitter.

2 Comments

  1. Pingback: Safer C# with the nameof operator - Kill All Defects

  2. Pingback: Quality Thoughts - November 2019 - Kill All Defects

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.