1
votes

I've read the docs for C# nullable reference types.

I'm unsure how to handle the case of the framework calling my methods.

A simple EF Core example:

protected override void OnModelCreating(ModelBuilder builder) 
{
     base.OnModelCreating(builder);
     builder.ApplyConfiguration(new CustomerConfiguration());    // <--- CA1062
}

This throws a warning CA1062:

In externally visible method 'void DbContext.OnModelCreating(ModelBuilder builder)', validate parameter 'builder' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument. csharp(CA1062)

I assume the framework is not going to send me null, so I see no point in checking for null.

How do I handle this scenario, namely: the framework calls my methods with arguments that cannot be null?

EDIT: my question differs from the linked one in that it's generic and specifically asks about C# 8's NRT feature. I only chose a related example. Thanks anyway for all those who helped.

2
So, you've got two assumptions - that the framework is your only caller and that the framework won't pass you null. Seems inserting a check here the verifies your assumptions might make sense. Do you perceive there being a large penalty in inserting this check?Damien_The_Unbeliever
@Damien_The_Unbeliever I know what you mean. But I've always resisted validating inputs sent to me by the framework. If I can't trust the framework, I'm in deep trouble. If there's a bug in the framework then I want my app to fail fast.lonix
Wanting your app to fail fast is a very good instinct -- but if you want that you should be extra invested in a parameter null check, as it's the best way of failing fast, as opposed to having to debug an NullReferenceException!Jeroen Mostert
@lonix are you sure they're framework inputs? A derived DbContext in a different assembly that doesn't have NREs enabled could pass a nullPanagiotis Kanavos
I see no reason to make any assumptions about where your parameters come from, unless your method is private and all the callers are trivially validated within the class itself. The framework is just written by human coders anyway, it's not infallible. I've yet to see the first code base where too much parameter validation was a bottleneck...Jeroen Mostert

2 Answers

2
votes

As per my comment, you can use a null-conditional operator ?. to only invoke the ApplyConfiguration method if builder is not null:

builder?.ApplyConfiguration(new CustomerConfiguration());?

From the docs:

A null-conditional operator applies a member access, ?., or element access, ?[], operation to its operand only if that operand evaluates to non-null; otherwise, it returns null.

Edit following discussing in comments

I think it makes sense to include an alternative which OP is already aware of but I'll show as a more comprehensive solution.

Rather than using the null-conditional operator (which would actually hide any problem is builder was actually null), simply test builder at the start of the method:

protected override void OnModelCreating(ModelBuilder builder) {
    if (builder == null) throw new ArgumentNullException(nameof(builder));
    base.OnModelCreating(builder);
    ...

This would then be a more comprehensive way of dealing with a null value builder because an exception will be thrown if you receive a null into the method.

1
votes

Another option is to disable diagnostic CA1062, if you feel that rule doesn't add any value in your scenario.

You can disable diagnostics at various levels and in different ways. Use an .editorconfig file to apply to a given subtree on disk. Use #pragma or GlobalSuppressions.cs to suppress specific areas in code.