Sometimes it might be useful to capture the name of the variable or parameter within the code to simplify error reporting or debugging.

I keep on encountering posts and comments saying that this is not possible in C#.

Well, it is not so. And there are multiple ways to do that.

Anonymous class approach

Given the C# code:

static void Main(string[] args)
{
  Console.WriteLine("Name is '{0}'", GetName(new {args}));
  Console.ReadLine();
}

The output would be:

Name is 'args'

Here’s the C# code that does this:

static string GetName<T>(T item) where T : class
{
  var properties = typeof(T).GetProperties();
  Enforce.That(properties.Length == 1);
  return properties[0].Name;
}

In the method above we use anonymous type declaration to capture name of the variable (thanks to the C# compiler features) and then use reflection to get the property name.

Performance is rather reasonable – 1000000 operations complete in 0,2 seconds. Still there is a trick to make code work even faster. It is called generic type caching:

static class Cache<T>
{
  public static readonly string Name;

  static Cache()
  {
    var properties = typeof(T).GetProperties();
    Enforce.That(properties.Length == 1);
    Name = properties[0].Name;
  }
}

static string GetName<T>(T item) where T : class
{
  return Cache<T>.Name;
}

As you can see, evaluation and reflection happen only once – when the we ask for the variable name for the first time. Every other call reuses the cached value.

This technique leverages specifics of static readonly members and could be applied to other scenarios, as well.

Expression approach

As it turns out, there is another, more simple approach to find out .NET variable name, that leverages the power of Linq Expressions:

static void Main(string[] args)
{
  var domain = "matrix";
  Check(() => domain);
  Console.ReadLine();
}

static void Check<T>(Expression<Func<T>> expr)
{
  var body = ((MemberExpression)expr.Body);
  Console.WriteLine("Name is: {0}", body.Member.Name);
}

By the way, this expression-based technique is called strongly-typed reflection, and it is a really handy tool in some situations.

It is quite flexible, too. Given the expression, we can get the name and the value of the variable. So you can do this as well:

static void Check<T>(Expression<Func<T>> expr)
{
  var body = ((MemberExpression)expr.Body);
  Console.WriteLine("Name is: {0}", body.Member.Name);
  Console.WriteLine("Value is: {0}", ((FieldInfo)body.Member)
    .GetValue(((ConstantExpression)body.Expression).Value));
}

The output will be:

Name is: 'domain'
Value is: 'matrix'

Note, that performance of this code (compared to the first approach) is a bit slower. With 1000000 operations it takes 3 seconds to get the name and 6 seconds to get the value. This might be or might not be an issue in your specific scenario.

I’m considering the second approach (just pulling the names) as the replacement for the name literals in the current declaration syntax of validation rules in the Shared Libraries:

Enforce.Argument(username, () => username, 
  StringIs.ValidEmail, StringIs.Limited(3,64));

Combining name and value in one expression is also really tempting, but I’d wait a bit to see if there is a way to statically cache compiled expressions.

You can subscribe to the RSS feed of this blog, if you are interested in more updates on this topic.

Posted in C#