3

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.

18
  • 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? Commented Jun 24, 2021 at 7:31
  • @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. Commented Jun 24, 2021 at 7:34
  • 2
    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! Commented Jun 24, 2021 at 7:38
  • 1
    @lonix are you sure they're framework inputs? A derived DbContext in a different assembly that doesn't have NREs enabled could pass a null Commented Jun 24, 2021 at 7:40
  • 2
    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... Commented Jun 24, 2021 at 7:41

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks! I didn't understand you the first time! Now I see what you're getting at. This would work, but conceals the problem.
Then again, this is a compile-time only thing, so on second thought it is probably perfectly valid. I was hoping there was some NRT magic to handle this case. Is this the only way? Is this how you would do it?
Not the only way - you could test whether builder is null and throw an ArgumentNullException if it is? That would probably be a more belt and braces approach?
Yeah, based on your answer and the comments above seems like those are the only options. Thanks again.
Yea I'll just live with it till then. Frankly the more I use NRT the more sad I am that they didn't annotate more of the framework.
|
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.