In the latest post on my series about C# 6’s features, I want to look at nameof expressions. There are times when you need the string value of variables or methods or classes in your code. That could be to return an argument exception, it could be to have some sort of property changed notification, or it could even be to get the string value of an enumeration value.
Previously, you had to either have “magic strings” in your application or any number of tricks to abstract away what are basically the magic strings. If you changed the name of a variable, parameter, method, class, or enum, nothing would ensure that you went back and updated your “magic strings”. Perhaps if you had written very finely-grained unit tests (and you remembered to update those when you changed a variable name), you might get a warning, but that is a tremendous amount of discipline. That’s where C# 6 is here to save our bacon.
As an example, here is something we might have done previously
public void Useless(string foo) { if (string.IsNullOrEmpty(foo)) { throw new ArgumentNullException("foo"); } return; }
You can see how I could change the parameter name from foo to something else and the compiler won’t care if I fix the call to ArgumentNullException() or not. However, nameof fixes and prevents that.
public void Useless(string foo) { if (string.IsNullOrEmpty(foo)) { throw new ArgumentNullException(nameof(foo)); } return; }
The benefit here is that if I change the parameter and forget to change nameof(foo) like this:
public void Useless(string bar) { if (string.IsNullOrEmpty(bar)) { throw new ArgumentNullException(nameof(foo)); } return; }
You actually will get a compile time error that says “The name ‘foo’ does not exist in the current context”. Some people hate using the compiler as a unit test, but I don’t. It is basically “round one” of testing. I think the issue arises when it is the the only means of testing used, but it is just another tool in the toolbox that we should use.
As I mentioned earlier, you can use it to get the names of classes, methods, and it lets you stop the SomeEnum.SomeValue.ToString() madness. It is the same syntax and would look like this
public class UselessClass { enum UselessEnum { UselessEnumValue } public void UselessMethod(string uselessParam) { Console.WriteLine(nameof(UselessClass)); Console.WriteLine(nameof(UselessMethod)); Console.WriteLine(nameof(uselessParam)); Console.WriteLine(nameof(UselessEnum)); Console.WriteLine(nameof(UselessEnum.UselessEnumValue)); } } // Later when called... var uselessObject = new UselessClass(); uselessObject.UselessMethod("uselessValue"); // Outputs these values /* UselessClass UselessMethod uselessParam UselessEnum UselessEnumValue */
As I said at the beginning of this series, much of C# 6’s features aren’t mind-blowing, but instead are small improvements to help smooth out some edges. Are you using nameof? Are you going to when you get the chance?