Caller Member Info, C#, and You
Tags: dotnet, csharp
Published: 2019-10-16 03:04:59

---
title: Caller Member Info, C#, and You
published: true
date: 2019-10-16 02:38:00 UTC
tags: dotnet, csharp
canonical_url: https://killalldefects.com/2019/10/15/caller-member-info-c-and-you/?utm_source=rss&utm_medium=rss&utm_campaign=caller-member-info-c-and-you
---

![Four "Hello my name is" nametags with the words "CalculateAnswer", "ExportGridContents", "FetchExternalData", and "HideBody"](https://i0.wp.com/killalldefects.com/wp-content/uploads/2019/10/image-6.png?fit=770%2C525&ssl=1)

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:

{% gist https://gist.github.com/IntegerMan/3afea2a503d4d0a5dfa1dbf047c1f906 %}

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

{% gist https://gist.github.com/IntegerMan/1c0b91e97bd201c35305a7036b1164b3 %}

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`](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callermembernameattribute) comes into play. Let’s take a look at an improved version of the code and then discuss how it works:

{% gist https://gist.github.com/IntegerMan/ff298c638df39e13fbdabdb1285f9429 %}

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:

{% gist https://gist.github.com/IntegerMan/fc59a9e3a09fa15581c0d712b9080ee8 %}

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](https://killalldefects.com/2019/08/29/making-defects-impossible/), 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](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callerlinenumberattribute) and [CallerFilePathAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.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](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/caller-information).

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](https://twitter.com/integerman).

The post [Caller Member Info, C#, and You](https://killalldefects.com/2019/10/15/caller-member-info-c-and-you/) appeared first on [Kill All Defects](https://killalldefects.com).