Background
Before starting, I must say that I am a great supporter of safety-features in programming languages, and I had proposed what I called the "required" keyword for C# more than 10 years ago. Yet, I keep seeing more and more people talking how great nullable reference types are in C# and, well, I am really unpleased on how badly the feature was implemented into the language, and this post is all about it.
(Non-)Nullable Reference (Types)
So, there are three things that I don't like in nullable reference types in C#:
- They are about non-nullable variables;
- They are not types;
- They might make your code vulnerable to attacks.
If those brief descriptions aren't enough, let me expand on each one of them:
1. They are about non-nullable variables
Calling the new feature "nullable reference types" commits two mistakes at once. In C# (and .NET) references were always nullables. What the new feature tried to add was non-nullable references (types). Well, the "types" part is what item number 2 is all about.
2. They are not types
Non-nullable references only exist at variable declarations, be them local variables, method parameters, return "types" (not sure the best word to use here) and fields. Yet, as a type, they are still the full nullable type. Although when writing them they might look the same as nullable vs non-nullable value types, non-nullable references still use the nullable types, while the actual types for nullable and non-nullable value types are different (like, Nullable<int>
and just int
).
3. They might make your code vulnerable to attacks
The entire purpose of adding non-nullable references is to avoid mistakes where null
values enter places where they shouldn't. Yet, the false security provided by (non-)nullable references is doing exactly the opposite. Many developers (be it by themselves, because of the tools they use or by practices enforced by the company where they work) are systematically removing null validations from their code, after all they are using non-nullable references. Unfortunately, non-nullable references can still be null and, if they aren't properly checked, nulls might enter data-structures that shouldn't allow null and cause errors to happen later. This actually introduces security vulnerabilities to components shared among different modules and threads, and makes the overall debugging experience harder, which is quite the opposite of what the feature was supposed to do.
How things could be better?
In concept, very simple. Non-nullable reference types should be their own types. They should be seen as distinct types from their nullable counterparts, possibly following the same pattern of nullable and non-nullable value-types, allowing even overloading between the nullable and non-nullable ones, and guaranteeing that the IL itself would never allow a non-nullable reference type to actually contain null, very similar to how C++ references work, as trying to cast a nullptr
to a reference will cause an immediate error.
Conclusion
The conclusion here goes to two different ways. The first is that non-nullable references are just a half-backed feature on its current implementation. I am not saying you should not use it, but be aware of its pitfalls.
This gets to the second conclusion, which is to keep validating your input values, even when they are not-supposed to be null, especially if you write shared libraries that might be used outside of your project, by other developers that might not be using the non-nullable references in their own projects.
I started to program computers when I was 11 years old, as a hobbyist, programming in AMOS Basic and Blitz Basic for Amiga.
At 12 I had my first try with assembler, but it was too difficult at the time. Then, in the same year, I learned C and, after learning C, I was finally able to learn assembler (for Motorola 680x0).
Not sure, but probably between 12 and 13, I started to learn C++. I always programmed "in an object oriented way", but using function pointers instead of virtual methods.
At 15 I started to learn Pascal at school and to use Delphi. At 16 I started my first internship (using Delphi). At 18 I started to work professionally using C++ and since then I've developed my programming skills as a professional developer in C++ and C#, generally creating libraries that help other developers do their work easier, faster and with less errors.
Want more info or simply want to contact me?
Take a look at:
http://paulozemek.azurewebsites.net/
Or e-mail me at: paulozemek@outlook.com
Codeproject MVP 2012, 2015 & 2016
Microsoft MVP 2013-2014 (in October 2014 I started working at Microsoft, so I can't be a Microsoft MVP anymore).