.NET - CallerMemberName, CallerFilePath and CallerLineNumber attributes How to use the attributes provided by the System.Runtime.CompilerServices namespace to get useful info about the execution context

.NET - CallerMemberName, CallerFilePath and CallerLineNumber attributes

If you're a seasoned .NET developer, you most likely know about the importance of logging: when used in an IT context, the term logging defines the process of keeping track of all the events occurring within the application (and their context information) and output them to a dedicated storage channel - be it a text file, a database table, and so on.

As we might easily guess, the primary purpose of logging is to keep track of the various interactions between the software and its users: state changes, access to internal resources, event handlers that trigger in response to user actions, exceptions thrown by internal modules, and so on.

Here at Ryadel we've published several posts about how to implement logging in .NET, by either leveraging the built-in ILogger interface or implementing a third-party solution such as Serilog. In this post we'll further expand that topic introducing three attributes provided by the System.Runtime.CompilerServices namespace that we can use to get useful info about the execution context, thus being very useful for logging purposes: CallerMemberName, CallerFilePath, and CallerLineNumber.

CallerMemberName

Let's start with the [CallerMemberName] attribute, which can be used to obtain the method or property name of the caller to the method.

Here's how we can use it:

As we can see by looking at the above code, the [CallerMemberName] attribute must be applied to an optional string parameter that has a default value: that parameter (memberName) will contain the name of the caller - in our scenario, the SomeTask method.

If the SomeTask method is executed, it will produce the following output:

That's a convenient way to retrieve the name of the caller member.

For further info and usage samples about the [CallerMemberName] attribute, check out the official docs.

CallerFilePath

The [CallerFilePath] attribute works in a similar way, but instead of retrieving the caller member's name, it will retrieve the full path of the source file that contains the caller: in other words, the class file path at the time of compile.

Here's how we can use it:

Again, the [CallerFilePath] attribute must be applied to an optional string parameter that has a default value: that parameter (filePath) will contain the source path of the caller.

If the SomeTask method is executed, it will produce the following output:

Obtaining such info can be very useful for logging purposes.

For further info and usage samples about the [CallerFilePath] attribute, check out the official docs.

CallerLineNumber

Having the member name and the source file can be great for error logging, as it allows us to instantly know the method that is not working as intended and its source file: however, if the method's implementation has several logging tasks, it might be hard to locate the precise line of code that called the log method which generated the log entry we are analyzing.

The [CallerLineNumber] attribute can be useful to fill that gap since it allows us to obtain the line number in the source file at which the method is called.

Here's how we can use it:

Notice how, this time, we used the [CallerMethodName][CallerFilePath], and [CallerLineNumber] attributes together,  to see how we can precisely locate the name, the source file, and the line number of the caller member.

If the SomeTask method is executed, it will produce the following output:

This information can be very useful to understand what happened and where.

For further info and usage samples about the [CallerLineNumber] attribute, check out the official docs.

Conclusion

The [CallerMethodName][CallerFilePath], and [CallerLineNumber] attributes can be very useful to obtain valuable info regarding our execution context: their ideal usage is for logging and monitoring purposes, but they can definitely come in handy in other scenarios as well.

 

About Ryan

IT Project Manager, Web Interface Architect and Lead Developer for many high-traffic web sites & services hosted in Italy and Europe. Since 2010 it's also a lead designer for many App and games for Android, iOS and Windows Phone mobile devices for a number of italian companies. Microsoft MVP for Development Technologies since 2018.

View all posts by Ryan

Leave a Reply

Your email address will not be published. Required fields are marked *

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