Who wants non-nullable types (I do, I do!)?

Many people were intrigued at Tech-Ed when Anders revealed the deep language integration we were giving to the new System.Nullable<A> type.  I could go more in depth into how it works, but for now I'll just to briefly explain it.  Nullable<A> attempts to give a type that everyone can use when trying to represent alue types that have no value.  This concept routinely comes up in database programming where you can have a field like 'age' that can be set to 'null' which indicates that you don't know what the value actually is.

Basically we've special cased Nullable<A> to be mixin of the form: Nullable<A> : A.  (we also let you simplify how you type it by writing “A?” to mean the same thing).  So where you need an A you can use an A? and you can treat an A? (more or less) as an A.  For example you could do:

            int? a;

            int? b;

            //stuff

            int? c = a + b;

I.e. we've allowed you to use the '+' operator on the int? the same way you'd use it on an int.  If eitehr of hte arguments are unset then c will be unset.

There's been a lot of debate over many parts of this feature, but one of the things that has come up is that we seem to be multiplying the number of ways you can say that something is null, and we've also added confusion into how all the different 'null' values interact.  What's interesting is that we haven't helped say something that many people want to say, namely that something is not null.  Checking that something is not null and dieing because of it is such a common behavior that i ended up writing something to handle it for me:

    public static class Argument

    {

        public static class Validate

        {

            public static void NotNull(object argument, string name)

            {

                Debug.Assert(argument != null);

                if (argument == null)

                {

                    throw new ArgumentNullException(name);

                }

            }

            //other validation methods

        }

        //other things you can do on an argument

    }

You would then use this by writing: 

Argument.Validate.NotNull(foo, "foo");

I'd much rather have a built in langauge feature, compile time checking, and BCL support for that kind of construct.  i.e. the ability to say something like:

string! s

Where the ! means “can't be null”.  You could then decorate your methods ending up with things like:   public string! SubString(int start, int end);, etc.

You could automatically pass an A! anywhere where you needed an A, and using the ! operator you could convert an A into an A! (throwing if the object as null).

This, like const, would require work but would be so valuable for the compile time verification of what is such a common problem.  Threading this through the BCL would make it safer, potentially catch bugs and would benefit everyone (except the poor BCL authors who would haveto retrofit their code).  But really, would the cost be that great?  You'd be able to _get rid of_ null reference checks everywhere.  If the compiler were really nice it would look for these issue and give you warnings.  i.e.:

if (null == foo)  //warns: foo can never be null, express will always be false

return foo //warns: return type of the method is a string but you always return a string! (a non null string, not a statement of exclamation ;-) ) consider having your method return type be string! instead.

What do you think?  Useful?

---

Edit: Eric discusses Nullable<A> as well

Edit: Luke discusses it as well, and delves into the issues integrating with the current BLC.