A Look at the Caller Info Attributes in C# 5.0

In C# 4.0 or earlier versions, to get the caller information at the called method the caller had to explicitly pass the information as a parameter or by some other means. In order to do that it had to use the Reflection classes that are available under the namespace System.Reflection.

Now C# 5.0 exposes a feature called Caller Info attributes in order to accomplish the task with ease. This article offers an insight about these attributes.

Caller Info Attributes

CallerInfo attributes are specifically designed to decorate the optional parameters of a method, which can then be used by the .NET runtime to inject the caller information. Below are some of the advantages of caller info attributes when compared to the traditional methods of passing the caller information.

1. The caller doesn’t have to do anything explicitly. Say for example I have built a component that is going to be used by a client application, using Caller Info Attributes I don’t have to worry about the caller passing the information explicitly; I will always get it through the caller info attributes.

2. There is no need for explicit usage of System.Reflection classes.

3. These attributes will be very helpful while implementing server side tracing or exception logging.

These attributes are encapsulated under the namespace System.Runtime.CompilerServices.

What are they?

There are 3 caller info attributes that come along with C# 5.0 and they are:

1. CallerFilePath

This attribute will provide the path of the file from where the method call is being made.

2. CallerLineNumber

This attribute will provide the line number from where the call is being made.

3. CallerMemberName

This attribute provides the name of the method that is making the call. It also has some special usages, which I will discuss later in this article.

Using Caller Info Attributes

In this section let us create a small application to demonstrate the usage of these CallerInfo attributes in C# 5.0. Create a console application and add the below mentioned code to Program.cs.

namespace CallerInfoAttributes
{
    class Program
    {
        static void Main(string[] args)
        {
            PrintCallerInformation();
 
            Console.ReadLine();
        }
 
        static void PrintCallerInformation([CallerLineNumber] int lineNumber = 0, [CallerFilePath] string filePath = "", [CallerMemberName] string memberName = "")
        {
            Console.WriteLine("Line number from where the call is made: {0}", lineNumber);
            Console.WriteLine("Filepath of the caller: {0}", filePath);
            Console.WriteLine("Member which is making the call: {0}", memberName);
        }
    }
}

When you execute the console application you will exactly see the Caller Info parameters that are being passed.

CallerMemberName – Specialty

The CallerMemberName attribute can be of some special use. For example if you want to decide the business logic based on the caller at runtime then CallerMemberName would help you. Below is a sample piece of code.

namespace CallerInfoAttributes
{
    class Program
    {
        static void Main(string[] args)
        {
            int i = 10;
            int j = 5;
            Add(i, j);
            Sub(i, j);
        }
 
        private static void Sub(int value1, int value2)
        {
            Compute(value1, value2);
        }
 
        private static void Add(int value1, int value2)
        {
            Compute(value1, value2);
        }
 
        private static void Compute(int value1, int value2, [CallerMemberName] string memberName = "")
        {
            if (memberName.Equals("Add"))
                Console.WriteLine("Sum = {0}", value1 + value2);
            else
                Console.WriteLine("Difference = {0}", value1 - value2);
        }
    }
}

Also if you are implementing the INotifyProperyChanged interface in your class, you would have been passing the member name as a hard coded string from the property setter while raising the PropertyChanged event. This can be avoided by using the CallerMemberName attribute.

The CallerMemberName would inject specific values based on the caller. Below is the list.

1. If caller is a Method, Property or an event then the name of the caller will be injected.

2. If the caller is a constructor or a static constructor then the value will be injected as .ctor or .cctor respectively.

This is all I had to share about the Caller Info attributes of C# 5.0. Happy reading!

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read