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!



Related Articles

Comments

  • Clean and Simple Article

    Posted by Senthil on 11/19/2013 08:43am

    Really nice article..Thanks Mr.Arun.

    Reply
  • .Get Grid

    Posted by jagvir on 10/26/2012 05:07am

    Data binding is used by almost all modern applications. It provides simple means to separate the data layer from the presentation layer. Generally, binding means connecting a graphical control property with a data object property. For example, if we have Product class, Label control can be bound to Name property of this control .net grid tutorial is very helpful

    Reply
  • Sir

    Posted by Rich on 10/22/2012 04:07am

    I agree the Add/Sub example is silly, but I think it was only meant for exposition. However, this facility could be great for INotifyPropertyChanged event handling. At the moment you have to require the function be called with a text string holding the name of the property being changed, and the opportunities for these to get out of sync and cause weird behaviour in your programs is huge.

    Reply
  • No changing behavior based on caller

    Posted by Foozinator on 10/18/2012 08:43am

    I can think of a few good uses for caller info (error logging is one), but having a method change behavior based on the caller method name sounds terribly dangerous to me. Debugging a problem could become significantly harder unless that behavior is well documented and easy to find.

    Reply
  • Ye gods, no! Please, no!

    Posted by Ross Patterson on 10/18/2012 05:05am

    "For example if you want to decide the business logic based on the caller at runtime then CallerMemberName would help you." Anyone who writes code that behaves differently depending on where it was called from should be shot, drawn and quartered, and given 50 lashes, not necessarily in that order. In fact, the very fact that caller info attributes enable such bad practice should argue against having them at all.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • As all sorts of data becomes available for storage, analysis and retrieval - so called 'Big Data' - there are potentially huge benefits, but equally huge challenges...
  • The agile organization needs knowledge to act on, quickly and effectively. Though many organizations are clamouring for "Big Data", not nearly as many know what to do with it...
  • Cloud-based integration solutions can be confusing. Adding to the confusion are the multiple ways IT departments can deliver such integration...

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date