Life and code.
RSS icon Home icon
  • New C# Operator

    Posted on July 27th, 2004 Brian No comments

    How many times have you written a piece of code like this?

    public void Jump(string msg)
    {
       if (msg == null || msg.Length == 0)
       {
          throw new ArgumentNullException("msg");
       }
    
       // Jump!
    }

    I don’t know about you, but I write code like this all the time. It’s an important sanity check, and Microsoft recommends it. But what happens if you change the name of the variable msg? Suddenly, your code is wrong. Sure, it’s syntactically correct and will compile just fine, but there is no longer a semantic link between the message returned by the ArgumentNullException and the code from which it was thrown.

    I propose the addition to the C# language of the nameof operator. Analagous to the existing typeof operator, the nameof operator will return the name of its operand as a string. The example from above, then, would be rewritten as follows.

    public void Jump(string msg)
    {
       if (msg == null || msg.Length == 0)
       {
          throw new ArgumentNullException(nameof(msg));
       }
    
       // Jump!
    }

    It is important to note that the operand is still a full-fledged symbol. Thus, in the example above, changing the name of the msg parameter will cause a compile-time error if the operand to the nameof operator is not also changed.
    The nameof operator will simply be syntactic sugar, and requires no changes to the CLR, and therefore also causes no change to the run-time performance of the code.

    Why is this important? After all, the above example is simplistic, even though it is a common case. First of all, there are many more complicated cases that can occur. As we all know, detailed error messages can go a long way towards helping troubleshoot and debug problems in our code. My own personal guidelines for creating error messages are:

    1. Error messages must be unique to a given error condition. You should never copy-and-paste error messages unless the root cause of the error really is identical; and in that case, you should think about refactoring your code because it sounds like you have some code duplication. (The exception to this (pun intended) is the catch syntax, which requires multiple blocks to catch exceptions that do not have the same root.)
    2. Error messages must have a detailed message explaining cause of the problem, including the names and values of any variables used to calculate the error condition.
    3. Error messages should include a description for how to correct the problem. This could be as simple as giving example known-good values, or it could be as complex as describing how to fix your Windows certificate store to have the right permissions.

    The nameof operator will go a long way towards ensuring consistency between error messages and code.

    The other need for the nameof operator is the increasing intelligence of the development tools. Refactoring tools have are quite in vouge, evidenced by the fact that Whidbey will be shipping with such tools bundled in. As we continue to do less and less manual editing of our code, relying on a developer’s eye to find and fix such problems becomes more and more dangerous.

    I came up with this idea when I was at Avanade working with Steve, but I’ve never mentioned it publicly. As I recall, at that time, Steve had the opportunity to have a quick chat with Anders Hejlsberg, the lead designer of C#, and he mentioned this. I seem to recall he liked the idea, but it was one of those little things that would probably never happen. Steve, am I making this up?

    Comments are closed.