I recently tried to enable nullable context for my C# projects. It is great mainly for the reason that if I use non-nullable types I can rely on a reference to have a proper object stored in it.
Or at least that's what I thought. Unfortunately, I sometimes see null references in my non-nullable types when I use external libraries. E.g
If I use
System.xml.serialization.xmlserialier.
Deserialize
()
and the resulting object has a non-nullable field. Deserialize would put null into fields of the returned object - even if they are non-nullable.I also use a 3rd party library called AutoMapper . The library has a similar behaviour - it just produces objects which violates the non-nullable assumption and I don't see an option to change this.
How do you deal with this situation? I am not sure if
I just have chosen my libraries badly and there are better libraries that do not write null to non-nullable fields.
I have to check all objects manually if they are coming from external code?
I completely missed the point of these non-nullable types...? I thought the idea is that I can rely on not having null for these types if my code does not spit out compiler warnings.
I tried to find specific solutions for the mentioned libraries. However both seem unaware and don't provide a flag "Throw exception if null" or similar.
True, but it's not a hard run-time guarantee. It's a "static code analysis" check at compile time, which is easy to "override":
You can use the null-forgiving operator
!
to assign null to a variable or field of a non-nullable reference type.You can use reflection to assign null.
VB code calling your C# library will happily ignore all the nullable annotations in your library.
In your compiled code, the field is technically still "nullable". Sure, the compiler will set helpful attributes and .NET 6+ even has an API to check for these attributes, but it's still "just" an annotation, not a run-time type check that will cause the CLR to bail out with an exception.
That's why, as a library developer, you still need to do runtime checks against null argument values:
Be careful with deserialization, object-relational mappers and other libraries which use reflection to dynamically fill your objects. Many of them have been written before nullable reference types were a thing. Check the documentation whether they respect nullability attributes or not. If they don't, validate your objects before using them.