I've been searching for some good guidance on this since the concept was introduced in .net 2.0.
Why would I ever want to use non-nullable data types in c#? (A better question is why wouldn't I choose nullable types by default, and only use non-nullable types when that explicitly makes sense.)
Is there a 'significant' performance hit to choosing a nullable data type over its non-nullable peer?
I much prefer to check my values against null instead of Guid.empty, string.empty, DateTime.MinValue,<= 0, etc, and to work with nullable types in general. And the only reason I don't choose nullable types more often is the itchy feeling in the back of my head that makes me feel like it's more than backwards compatibility that forces that extra '?' character to explicitly allow a null value.
Is there anybody out there that always (most always) chooses nullable types rather than non-nullable types?
Thanks for your time,
The reason why you shouldn't always use nullable types is that sometimes you're able to guarantee that a value will be initialized. And you should try to design your code so that this is the case as often as possible. If there is no way a value can possibly be uninitialized, then there is no reason why null should be a legal value for it. As a very simple example, consider this:
List<int> list = new List<int>()
int c = list.Count;
This is always valid. There is no possible way in which c
could be uninitialized. If it was turned into an int?
, you would effectively be telling readers of the code "this value might be null. Make sure to check before you use it". But we know that this can never happen, so why not expose this guarantee in the code?
You are absolutely right in cases where a value is optional. If we have a function that may or may not return a string, then return null. Don't return string.Empty(). Don't return "magic values".
But not all values are optional. And making everything optional makes the rest of your code far more complicated (it adds another code path that has to be handled).
If you can specifically guarantee that this value will always be valid, then why throw away this information? That's what you do by making it a nullable type. Now the value may or may not exist, and anyone using the value will have to handle both cases. But you know that only one of these cases is possible in the first place. So do users of your code a favor, and reflect this fact in your code. Any users of your code can then rely on the value being valid, and they only have to handle a single case rather than two.