The purpose of the feature is to give developers more tools to catch the most prevalent type of errors there is, derefencing a null reference / pointer and thus crashing the application.
As such, the C# design team added "nullable reference types", with enough syntax that the developer can more clearly declare the intent and requirements of code.
Things that can be expressed by the new syntax:
- Properties and fields that either allow NULL or does not allow NULL
- Method parameters that can be NULL, or should be NULL
- Method return values that can be NULL, or won't be NULL
When enabled, the compiler will use this new syntax, and attributes and other metadata, to start giving warnings when it sees code that isn't "guaranteed" to be correct. In other words, if you read a property that says it can return NULL, and try to just pass that in as a parameter value where the method says that the parameter shouldn't be NULL, you will get a warning.
You can, using existing directives on projects, say that certain warnings should instead be handled as errors, and break the build, and this includes these new warnings.
HOWEVER, what they didn't add was runtime checks. If you say that a parameter value should never be NULL, and either ignore the warning or bypass it (there are ways to say "trust me, this is correct"), then the method will run as stated. There are no invisible if-statements or guard statements that verify that the parameter is not null.
Basically, you should still add such if-statements.
This is, contrary to your belief, exactly what they designed the feature to do. They did not forget to add these runtime checks, they purposefully didn't add them.
For instance, if you call a method through reflection, the compiler is not involved since it is a runtime thing, and thus no checks will be performed at all. If the method doesn't have such guard statements, likely it will crash later with a NullReferenceException.