Apparently the vast majority of errors in code are null reference exceptions. Are there any general techniques to avoid encountering null reference errors?
Unless I
Plain Code Solution
You could always create a struct that helps catch null reference errors earlier by marking variables, properties, and parameters as "not nullable". Here's an example conceptually modeled after the way Nullable
works:
[System.Diagnostics.DebuggerNonUserCode]
public struct NotNull where T : class
{
private T _value;
public T Value
{
get
{
if (_value == null)
{
throw new Exception("null value not allowed");
}
return _value;
}
set
{
if (value == null)
{
throw new Exception("null value not allowed.");
}
_value = value;
}
}
public static implicit operator T(NotNull notNullValue)
{
return notNullValue.Value;
}
public static implicit operator NotNull(T value)
{
return new NotNull { Value = value };
}
}
You would use very similar to the same way you would use Nullable
, except with the goal of accomplishing exactly the opposite - to not allow null
. Here are some examples:
NotNull person = null; // throws exception
NotNull person = new Person(); // OK
NotNull person = GetPerson(); // throws exception if GetPerson() returns null
NotNull
is implicitly casted to and from T
so you can use it just about anywhere you need it. For example you can pass a Person
object to a method that takes a NotNull
:
Person person = new Person { Name = "John" };
WriteName(person);
public static void WriteName(NotNull person)
{
Console.WriteLine(person.Value.Name);
}
As you can see above as with nullable you would access the underlying value through the Value
property. Alternatively, you can use explicit or implicit cast, you can see an example with the return value below:
Person person = GetPerson();
public static NotNull GetPerson()
{
return new Person { Name = "John" };
}
Or you can even use it when the method just returns T
(in this case Person
) by doing a cast. For example the following code would just just like the code above:
Person person = (NotNull)GetPerson();
public static Person GetPerson()
{
return new Person { Name = "John" };
}
Combine with Extension
Combine NotNull
with an extension method and you can cover even more situations. Here is an example of what the extension method can look like:
[System.Diagnostics.DebuggerNonUserCode]
public static class NotNullExtension
{
public static T NotNull(this T @this) where T : class
{
if (@this == null)
{
throw new Exception("null value not allowed");
}
return @this;
}
}
And here is an example of how it could be used:
var person = GetPerson().NotNull();
GitHub
For your reference I made the code above available on GitHub, you can find it at:
https://github.com/luisperezphd/NotNull