Tuesday, April 3, 2012

Non-nullable value type error

The Problem
Working with XNA to develop a game for Windows Phone 7, I came across this issue of non-nullable values. What I was trying to do was simple. Given the coordinates of a touch position x and y, give me the color of the object at that position if any. Otherwise, return null.


        public Color getObjectColorAtPosition(float x, float y)
        {
            for every object in the list of objects:
                if there is a match with x and y
                    return the color of the object

             //since we did not find any match to the given x and y
             return null;
        }

But it didn't like it and I got the following error:
"Cannot convert null to 'Microsoft.Xna.Framework.Color' because it is a non-nullable value type"

You will get a similar error if you try to nullify Vector2,  GestureSample, TouchCollection, and of course many other types. For example, you will get a similar error if you try to do:

Vector2 vector = null; 

The Solution
To state the obvious, you need to change the non-nullable type into a nullable one. And this is how you do it:


        public Color? getObjectColorAtPosition(float x, float y)
        {
            for every object in the list of objects:
                if there is a match with x and y
                    return the color of the object

             //since we did not find any match to the given x and y
             return null;
        }

Nothing changed except the question mark next to the return type of the function. In a similar way you can declare Vector2 as:


Vector2? vector = null; 


But then if you want to access the content of the Vector2? object, you will have to do it through the Value field:

vector.Value.X = 4;
vector.Value.Y = 2;

Essentially what you are doing here is wrapping the non-nullable type within a nullable one. The longer method of doing this is by creating a Nullable instance:

Nullable<Vector2> vector = null;

Why is this happening in the first place? 
Well.. Ask Microsoft. But here is a quick glimpse. Some language developers think it is a better practice to not allow null as a sentinel value for struct objects or even class instances. This way, the object can be used anywhere in your program without having to verify that it is not null.

Others, including me, think that this is not something the language has to concern itself with. Leave it up to the developer to decide how to deal with null values. Or at least make it the other way around so that the developer has to specify (with a question mark) if an object should be non-nullable.

A funny comment I read on this topic: "what's next? non-zero integral types to avoid divide by zero?"

No comments:

Post a Comment