Nullable Reference Types

Nullable reference types is a new feature introduced in C# 8. In short, when it is enabled, any type that is not explicitly marked nullable cannot be null or it will produce a warning or error (depending on how strict it is configured). This is already the case with structs, enums and primitive types and would just extend to normal classes too.

Here is some sample code:

string a = null; // Error or warning depending on how strict it is set
string? b = null; // Works fine, string is now declared nullable

public void DoSomething(string? someParameter)
{
    someParameter.Something(); // Error or warning: someParameter can be null here
}

The compiler can also analyze when a variable cannot be null:

if (someParameter != null)
{
    someParameter.Something(); // no error or warning
}

Proposal

I think the S&box API should at least be nullable annotated so that addons which want to enable nullable reference types can utilize it fully. It also makes clear what methods expect and return, e.g. if the return value and parameters can be null or not.

Why

Remember all the nil spams in Garry’s Mod? We surely don’t want to have the same in S&box with NullReferenceExceptions. This is not just an issue related to Garry’s Mod, it is a general issue in programming languages that have a concept of null. Tony Hoare, the inventor of null, called it his billion dollar mistake in 2009 for that very reason.

I believe having this enabled by default for new addons (either as warning or even better as error) would improve the overall quality of addons. It does not make writing addons any harder either. Anyone who has used nullable structs or nullable ints already knows how it works. In any case, addons should be able to either disable or enable this depending on their own needs.

Examples

Here is an example issue from OpenMod that was reported before OpenMod enabled nullable reference types:

After I have enabled nullable reference types and started migrating existing code to it, the compiler started erroring out related code:


With nullable reference types I was able to fix known bugs like this immediately.

Enabling nullable reference types also helped discovering many yet unknown bugs, like this one:

User data was never loading from disk as m_CachedUsersData never could be null.

Here is the related commit for reference. It took about 2 days to convert this project which consists of about 30k lines of code.

14 Likes

I 100% agree. This will definitely solve some of the problems I’ve run into programming on older versions of C# having to go at it in a roundabout way when a reference type could just be passed as NULL instead.

I’m not aware of any reason as to why this would not be implemented anyways, but I’d like to know why if that’s the case.

5 Likes

I kind of agree but it feels like something we should have done from day one. I’ll put it on my list of things to look at and work out how much pain it would be.

22 Likes

Although it would mean a lot of refactoring, it would be better to implement it now, because then it will be even more work in the future? Or maybe only enforce it as a default setting that can be turned off when developing an addon, so that the internal code can stay the same?
This doesn’t only improve code stability, but also speeds up coding, because you encounter less bugs that can be annoying to find (although most NullReferenceExceptions can mostly be fixed in 10 seconds).
It always surprises me how great C# can be and how much more it can do (in comparison to Java for example).

4 Likes