It would be so cool to be a language designer working on the next version of C#. So cool infact that I am compelled to offer up my $0.02 worth on this particular feature request in the vain hope that I will be selected to replace Eric when he finalises his transition to being a hacker on the Movie Maker team.

When I first looked at the problem I kind of went off on a tangent thinking about automatic defaults and how that could be archieved elegantly - taking inspiration from the Nullable<T> generic type.

Eventually I determined that didn't really answer Eric's questions directly so I have shelved that idea for a little while and have gone back to what Eric's user asked:

When I'm writing code, I often come across a situation where my code throws an exception because another component called with a null parameter. I'd like a way to prevent that from happening.

Prevent what from happening? Prevent your code from executing at runtime or prevent the calling code from calling your code with a null reference at compile-time?

Given that there are two (atleast) possible scenarios here lets look at what I think is probably the easiest first.

PREVENTING YOUR CODE FROM EXECUTING WHEN IT IS PASSED NULL

In this scenario, you really just want to save yourself some typing by using a keyword to replace a number of very simple assertions at the beginning of a method. The feature might look something like this:

public void DoSomething(notnull SomeType someArgument)

{

}

By decorating a method argument with the "notnull" keyword you would be instructing the compiler to inject a null reference check at the beginning of the method, which would result in code like this:

public void DoSomething(SomeType someArgument)

{

    if (someArgument == null)

    {

        throw new ArgumentNullException(

            "someArgument",

            "Cannot be null"

            );

    }

}

That is an elegant solution I think, but it does add Yet Another Keyword (YAK) which is definately not something to be done lightly. YAK looks a lot like YUK - and I don't think that is a conincidence. I like to think of the use of keywords (and special symbols) as a kind of tax, ad we don't want to pay too much tax, especially when we aren't getting value for money. Effectively for the "notnull" keyword we would be getting the compiler to perform a very simple null check when the method executes, there are probably dozens of other types of checks that we would want to perform so our code can "fail early" - do we just want this one because we do it so often?

OK - so I have put up a possible implementation of the feature, lets try and answer Eric's questions.

What are the pros and cons of such a feature?

On the pro-side this could eliminate a lot of boiler plate code which causes code to fail early. However coming down on the con-side I think that we aren't getting alot of adding another keyword. I have an auxilary question based on experience - most people don't bother validating their inputs, particularly in tightly coupled code (although the scenario the user presented was components), given that people don't bother doing it - would it really only be helping a small number of users. Do we want to add a keyword to reduce a small amount of code for a small amount of users?

What are the ramifications of adding it to the language?

We would need to think about how it would look in the context of other argument modifiers:

Legal: public void DoSomething(notnull SomeType someArgument);

Legal: public void DoSomething(notnull ref SomeType someArgument);

Illegal: public void DoSomething(notnull out SomeType someArgument); 

Obviously it wouldn't make any sense to specify that an out param can't be null.

What would have to change?

There would need to be a few changes to properly support this RUNTIME feature.

  • The C# spec would need to be updated, which means that you would need to go into bat for the feature with ECMA. That would likely lead to a whole bunch of discussions about why this feature over something like Eiffel's invariants (has this been done to death yet? I dunno).
  • On the implementation detail side, the compiler would need to be touched to parse the keyword, check for errors in the context that it is used and inject the code into the top of the method.
  • The VS code editor would need to be updated to support things like syntax highlighting/intellisense.
  • There might be a case for the CodeDom pieces in the framework to be updated, especially if the VB team decided to go for feature parity on this one.

What is your recommendation?

Its not a high-value change for me - it doesn't buy me enough productivity especially when we have things like expansions to assist us in producing code which can then me modified to be much more expressive. Unless I had a lot of requests for this feature I would put it on the think about later pile.

PREVENTING YOUR USERS CODE FROM COMPILING AT COMPILE TIME

In this scenario you are more about defining a contract which you want your calling code to conform to. This has some interesting implications because there is no IL token that conveys this calling convention so assuming that you can't change the IL spec (an assumption at this point) then the only thing that you have left is an attribute that gets injected by the compiler, for example:

public void DoSomething(notnull SomeType someArgument)

{

}

The compiler would convert this to:

public void DoSomething([NotNull()] SomeType someArgument)

{

    if (someArgument == null)

    {

        throw new ArgumentNullException(

            "someArgument",

            "Cannot be null"

            );

    }

}

OK, so it works the same way as the previous scenario except for an additional attribute being injected into the argument list. This attribute has no run-time behaviour, its actually for the various code editors and compilers to take advantage of to give the user a warning or error about passing a null into a method (squiggly lines and all that). Now that I have thrown it out there, I think I need to tear it down by listing some of the many issues I see with it.

What are the pros and cons of such a feature?

OK, lets start of with the pros first. It has all the benefits of the first scenario, plus the not null convention can potentially be detected by code editors and compilers (languages) so that they can support it. This pro is also its greatest con, if the other editors and languages out there don't honor it there isn't a lot you can do about it, which is why you would need to still do the injection to enforce it at runtime. Another big con would be the complexity it would add to all compilers if they did choose to implement it - you see depending on the implementation of the compiler they may not know what the value of a reference is likely to be at the call-site. If I were the developer working on a these compilers (even the C# compiler) I'd probably moan, at least a little . . .

What are the ramifications of adding it to the language?

Mentally cut and paste the code from scenario one here, now consider the calling code for a little bit, imagine that you had a green hacker who is the sort of person who would write this C# if checked exceptions were supported.

try

{

    // Do something like connect to a database.

}

catch (CheckedException)

{

    // Yes, this is really empty.

}

Have I set the stage sufficiently? OK - now imagine that you were calling the DoSomething method that expected a SqlConnection (the fact that it is a SqlConnection has nothing to do with the previous code snippet) to do its work, our sample coder might initially do something like this.

DoSomething(null);

That would result in a compiler error, something like:

CSxxxx: You can't pass in null for "connection" dodo.

Mr. Green Hacker would then go and type in something like this:

SqlConnection connection = new SqlConnection();

DoSomething(connection);

And who could blame him - the compiler error told him that he can't pass null in there so he did the absolute minimum to get past the compiler error not even stopping to consider that it might need to be open or indeed in any specific state. Unfortunately the "notnull" is certainly a valid pre-condition, but its not all encompasing.

I'm also conscious of a discussion I had with Joel Pobar (CLR team) and Greg Low (UG Leader) over dinner one night at TechEd NZ about the various costs associated with decorating methods with attributes. I don't know if it is large enough to worry about if this feature was used infrequently but I could easily imagine some bright spark making [NotNull()] everywhere a best practice for some organisations.

What would have to change?

In addition to the changes mentioned in the previous scenario:

  • The compiler and syntax highlighter would need to be modified to make a reasonable guess about the state of a variable when the DoSomething(...) method was called. This could be non-trivial depending on the specific implementation of the compiler (I'm downloading ROTOR now to make an educated guess).
  • The above would have to happen for EVERY language which wanted to support the NotNullAttribute and the NotNullAttribute would need to be added to the BCL.

What is your recommendation?

I like this feature more than the first scenario because it delivers more value, but because of the wide-spread changes required to C# but also other languages I wouldn't go for it - once again, not unless I had a huge amount of requests for it - and I don't think there would be based on my experience - but then I don't read Eric's mailbox :P

Loose Ends

One thing that I haven't really talked about is the usage of the "notnull" keyword on properties (and potentially even fields). On properties you could have some syntax like this:

public notnull string FirstName { . . . };

It would also need to work with property indexers (more changes) and even things like anonymous methods - this change really has a bit of a ripple effect.