I was reading up on the development on Spec# and at the same time trying to figure out if we would start to see Spec# features in C#, anytime soon… Unfortunately, I don’t think we will find any Spec# features in C# 4.0, but I hope the team will prove me wrong.
If you haven’t looked at Spec# yet I strongly encourage you to take a look at it. The short story is that it is a research project which focuses on adding contract oriented constructs to the C# language. You can read more about it at the Spec# homepage or watch the Spec# introduction video on Channel9 which shows off some of the very cool features contract oriented programming brings to the table.
One of the features of Spec# is non-nullable types which is a type wrapper for reference types, sort of like the Nullable<T> type we got in C# 2.0 for value types, but with opposite meaning. In Spec# non-null types can be written as “object!”.
When a type is wrapped with the non-nullable type it can never be set to null. I hope you are now starting to think; “Cool, that would be a nice feature to have in C#”… If you are not, let me explain why you should.
Imagine a world where you could avoid writing code like this:
Instead you could let the language and the compiler do the null checks for you. If you are a developer by profession, think back on all the applications you’ve made and think of all the null-checking code you’ve written that you could’ve avoided if you had the non-null type feature. Or better yet, think of all the null-checks you forgot to write and you then later discovered when a tester or customer reported an error that turned out to be a null reference exception. Ahh yes, those were the days, right?
Now, since we don’t expect Spec# features in C# anytime soon is there any way we might be able to implement this functionality with what we have? How would we go about writing a non-null type in C#? Well, a good place to start is to fire up reflector and look at how the Nullable<T> type is implemented. After doing that and looking at Jon Skeet’s proposal, I came up with the following slightly modified code:
But as Jon points out in his excellent blog post that would cause a big problem, since a struct always adds a default parameter-less constructor (that you can’t directly customize) it would be possible to instantiate a NonNull variable with the empty constructor, and thus let the non-null type contain a null value which it clearly shouldn’t. Jon solved this problem by putting a null check in the getter of the “Value” property but this would still hide a potential null reference error till pretty late in a runtime flow. The good news is I found a different solution.
After doing some research I found out that MSIL doesn’t require a default empty constructor to be empty. I then simply compiled a version of the code that had an extra constructor with a dummy parameter and then deleted the parameter from the compiled assembly using the awesome Reflexil plug-in for reflector. And presto, one nice little generic NonNull type wrapper was born. The final code used for this type was:
As you can see I opted to mark the default constructor as obsolete because that gives a nice little compile-time error if it’s used. I’m also throwing a NotSupportedException from the constructor if it happens to be executed by reflection. I realize that this class isn’t as user-friendly as you would like it to be, but for now it’s probably the closest we’ll get without help from the C# language team.
If you would like to try it out you can get a precompiled NonNull type here. Enjoy!
Update (Oct. 11 2011, really REALLY late at night):
Akash asked in the comments if I've ever used this technique in production . And as I said in the comments, the short answer is... No, I have not used it in production because it doesn't work. Let me elaborate...
The reason why it doesn't work is simple. Firstly you have to declare the NonNull type as a struct to make the NonNull type itself non-nullable, I mean if you made something like this:
public class NonNull<T> where T : class
Then you could simply assign null wherever you use the type, like this:
NonNull<object> canBeNull = null;
It simply has to be a value type and not a reference type. Secondly, while the empty constructor trick might seem clever (I thought so at the time) it simply doesn't work. Sure, you can't call the empty constructor directly. But if you do something like:
var myNonNullableVariable = default(NotNull<object>);
Then you would get a NonNull<object> which has a null value. There are no ways to overcome this, but you could copy the null check from the constructor into the getter, but I wouldn't recommend that you do that, or use this NonNull struct at all. As long as there isn't any language/designer support for this wrapper it isn't that valuable.
Fortunately there are other ways to get this functionality if you use Visual Studio 2010 and .NET 4. What you could use is the code contract stuff in. In the original blog post I mentioned Spec#, since then this project was partly rolled into .NET 4.0 and Visual Studio 2010. Again, this happened long after I originally wrote this post but it can be useful. You can find information about code contracts here: http://msdn.microsoft.com/en-us/magazine/ee236408.aspx
Just remember to use code contracts moderately and not go overboard. Code contracts can be extremely useful, especially in large/complex projects. However, I've rarely used them myself.

2 comments: