C#6: The nameof Operator

Before discussing the `nameof` operator in C#6, I want us to consider why `nameof` exists at all. So, let's head back ten years to the heady days of 2005.

Wayne's World Flashback

When version 2.0 of the .NET framework arrived, it transitioned the fledgling platform from a sketch of what might be to a fully-formed platform that could support ongoing and future desktop and web development. Since then, each release of the framework and its associated languages have added a variety of bells and whistles that simplify and enhance the way we develop. Among many of the concepts and types introduced by .NET 2.0 was `System.ComponentModel.INotifyPropertyChanged`, part of the enhanced data binding introduced to Windows Forms development. This interface turned out to be a workhorse and introduced many developers to a new problem; making sure the string that named a variable matched the name of an actual variable.

Now, you may well object to this claim since various versions of `ArgumentException` already demanded this of developers, but I think we both know that until our tooling got smarter (like FxCop and Resharper), many of us just did not fill that argument out if we could help it. After all, the stack trace would tell us where the crash happened, we could put something meaningful in the exception message, and keeping that variable name up-to-date after refactoring was a pain. With the advent of `INotifyPropertyChanged` the benefit of putting the variable name in a string started to outweigh the costs. Quickly, patterns emerged to try and simplify this, from dubiously performant uses of reflection to build-time code generation. As tools matured, we could get refactorings that took these strings into account and warnings that could shout at us if a variable was mentioned that didn't exist. Few of these were particularly elegant or entirely foolproof, and none were both1. In addition to `ArgumentException` and `INotifyPropertyChanged`, property names would be used for logging and debugging.

In the Name of Progress

There were calls for a new operator to accompany `typeof`; the new operator, `infoof`2 would provide the corresponding reflection information of a particular code construct (like `MethodInfo` or `PropertyInfo`), simplifying not just obtaining the name of something, but also any reflection operation involving that something. All this use and discussion of meta-information did not go unnoticed. Eric Lippert blogged about `infoof` and why it would be useful, why it was so difficult to implement, and indirectly foreshadowed where we would be today. However, amid the discusson, there was little action.

In 2012, .NET 4.5 brought us the `CallerMemberNameAttribute` type and its siblings, `CallerLineNumberAttribute` and `CallerFilePathAttribute`. These new attributes enabled developers to decorate method arguments, indicating that the appropriate piece of information was to be injected into that argument when the method was called. This fell short of an `infoof` operator, but it greatly simplified use of `INotifyPropertyChanged` (and `INotifyPropertyChanging`, introduced in .NET 3.5). Alas, argument exceptions, logging, debugging, and other uses of method, variable, and property names were left as they were, often leading to mismatched error messages, obscure data binding bugs, and other problems.

That changed in 2015 with the new releases of both .NET and C#, and the new `nameof` operator in C#6. The `nameof` operator is sublimely simple; in fact, its concept seems so obvious that it's a wonder it took so long to appear3. Using `nameof`, we can inject the names of variables, types, methods, events, and properties into all sorts of places at compile-time4, knowing that if we change the name, our refactoring tools can update all references with confidence. Not only that, but our intent is clear; we want the name of this thing to be here and not just some string that happens to look like the name of some thing. While the `nameof` operator does not replace `CallerMemberNameAttribute`, which so deftly simplified `INotifyPropertyChanged`5, it does simplify other scenarios like throwing `ArgumentException`, logging errors, and outputting debug information.

In Conclusion

When I first contemplated writing a whole blog entry dedicated to `nameof`, I thought it was too simple a feature to warrant such focus; now I have finished, I believe `nameof` to be entirely worthy of the attention. Along with the fantastic string interpolation in C#6, I believe `nameof` is one of the simplest and most useful additions to the C#6 language. Like many C# and .NET features we now take for granted, `nameof` is a beautifully simple concept that we will come to rely upon. I believe it will save us countless hours of fixing erroneous refactoring, arguing over coding style and code reviews, and head-scratching at spurious errors.

  1. IMHO []
  2. pronounced, "Info Of" []
  3. As is often the case in software development, we were all too busy discussing the most complex use-case we could think of rather than the one that really needed solving []
  4. unlike reflection-based solutions that do all the work at run-time []
  5. `nameof` does provide an alternative, more wordy alternative for that scenario []

Unit testing attribute driven late-binding

I've been working on a RESTful API using ASP WebAPI. It has been a great experience so far. Behind the API is a custom framework that involves some late-binding. I decorate certain types with an attribute that associates the decorated type with another type1. The class orchestrating the late-binding takes a collection of IDecorated instances. It uses reflection to look at their attributes to determine the type they are decorated with and then instantiates that type.

It's not terribly complicated. At least it wasn't until I tried to test it. As part of my development I have been using TDD, so I wanted unit tests for my late-binding code, but I soon hit a hurdle. In mocking IDecorated, how do I make sure the mocked concrete type has the appropriate attribute?

var mockedObject = new Mock();

// TODO: Add attribute

binder.DoSpecialThing( mockedObject.Object ).Should().BeAwesome();

I am using Moq for my mocking framework accompanied by FluentAssertions for my asserts2. Up until this point, Moq seemed to have everything covered, yet try as I might I couldn't resolve this problem of decorating the generated type. After some searching around I eventually found a helpful Stack Overflow question and answer that directed me to TypeDescriptor.AddAttribute, a .NET-framework method that provides one with the means to add attributes at run-time!

var mockedObject = new Mock();

TypeDescriptor.AddAttribute(
    mockedObject.Object.GetType(),
    new MyDecoratorAttribute( typeof(SuperCoolThing) );

binder.DoSpecialThing( new [] { mockedObject.Object } )
    .Should()
    .BeAwesome();

Yes! Runtime modification of type decoration. Brilliant.

So, why didn't it work?

My binding class that I was testing looked a little like this:

public IEnumerable<Blah> DoSpecialThing( IEnumerable<IDecorated> decoratedThings )
{
    return from thing in decoratedThings
           let converter = GetBlahConverter( d.GetType() )
           where d != null
           select converter.Convert( d );
}

private IConverter GetBlahConverter( Type type )
{
    var blahConverterAttribute = Attribute
        .GetCustomAttributes( type, true )
        .Cast<BlahConverterAttribute>()
        .FirstOrDefault();

    if ( blahConverterAttribute != null )
    {
        return blahConverterAttribute.ConverterType;
    }

    return null;
}

Looks fine, right? Yet when I ran it in the debugger and took a look, the result of GetCustomAttributes was an empty array. I was stumped.

After more time trying different things that didn't work than I'd care to admit, I returned to the StackOverflow question and started reading the comments; why was the answer accepted answer when it clearly didn't work? Lurking in the comments was the missing detail; if you use TypeDescriptor.AddAttributes to modify the attributes then you have to use TypeDescriptor.GetAttributes to retrieve them.

I promptly refactored my code with this detail in mind.

public IEnumerable<Blah> DoSpecialThing( IEnumerable<IDecorated> decoratedThings )
{
    return from thing in decoratedThings
           let converter = GetBlahConverter( d.GetType() )
           where d != null
           select converter.Convert( d );
}

private IConverter GetBlahConverter( Type type )
{
    var blahConverterAttribute = TypeDescriptor
        .GetAttributes( type )
        .OfType<BlahConverterAttribute>()
        .FirstOrDefault();

    if ( blahConverterAttribute != null )
    {
        return blahConverterAttribute.ConverterType;
    }

    return null;
}

Voila! My test passed and my code worked. This was one of those things that had me stumped for longer than it should have. I am sharing it in the hopes of making sure there are more hits when someone else goes Internet fishing for help. Now, I'm off to update Stack Overflow so that this is clearer there too.

  1. Something similar to TypeConverterAttribute usage in the BCL []
  2. Though I totally made up the BeAwesome() assertion in this blog post []