DEV Community

Caller Member Info, C#, and You

Matt Eland on October 16, 2019

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...
Collapse
 
johnn6tsm profile image
JohnN6TSM

I used callerfilepathattribute to create a slick unit Test database. I store data for a unit test method in a file next to the source file. I have a test method that writes its argument to the database if shift and alt are down, otherwise it checks the string against the database. Makes it easy to veeify complicated strings have not changed.

Collapse
 
integerman profile image
Matt Eland

This sounds similar to how Snapper works for identifying snapshot files for a unit test.

Collapse
 
seangwright profile image
Sean G. Wright

I've used this in the past for some internal infrastructure pieces... but the one thing I don't like about this attribute is that it requires you to add a parameter to a method that the caller should not use.

It's like I create an API and expose something that I don't want the caller to use.

public class Logger
{
    public void Log(string message, string doNotUseThisParameter);
}

This breaks several SOLID principles and is downright confusing for those not familiar with how the [CallerMemberName] attribute works.

So, I normally don't expose any infrastructure that uses it and I try to keep its use very limited.

That said, it can be useful, and I'm sure there are devs out there that will discover it through this post.

Thanks!

Collapse
 
luturol profile image
Rafael Ahrons

Loved the article!!

Didn't know about this feature until now. When should I use it instead of overload or just passing an nullable parameter?

Collapse
 
integerman profile image
Matt Eland

My argument is that you should always use CallerMemberName in cases where you want to pass a member name as it prevents mistakes.

Really, the only scenario I could use it and don't is like this:

public void LogSomething(string message, [CallerMemberName] caller = "")
  => LogSomething(message, LogPriority.Normal, caller);

public void LogSomething(string message, LogPriority priority, [CallerMemberName] caller = "") {
  // Do some logging
}

In this example, if I didn't pass in caller to the other method via the overload, caller would default to LogSomething.

So, really, that's the only case where I would explicitly set caller - when I need to pass data around and don't want CallerMemberName to overwrite the value.