C# What is the best way to RESOLVE the warning compilation "CS8618"

226 views Asked by At

If we declare property like this:

public class Cat
{
    public string Name { get; set; }
}

we get a warning compilation:

CS8618 - Non-nullable variable must contain a non-null value when exiting constructor. Consider declaring it as nullable.

because Name property is not initialized.

Imagine, this is mandatory property (business rules say it). We can try to solve it by several ways:

  1. Constructor declaration:

a) In ctor directly:

public class Cat
{
    public Cat()
    {
        Name = string.Empty;
    }
    public string Name { get; set; }
}

b) in property:

public class Cat
{
    public string Name { get; set; } = string.Empty;
}

really, both options is the same (syntax sugar).

pros: we can use init of class like Cat cat = new ();

cons: property is initialized by 'dummy' value when object is created and will be rewritten. Or (much more major) will not be rewritten by some unknown reasons (e.g. we use automapper and source object had empty value for this field or we forgot to map this field) and in result object will have invalid value (by business rules property can't be empty, cat must have a name)

  1. declare field as nullable:
public class Cat
{
    public string? Name { get; set; }
}

for me, it's invalid approach (although it's described here as alternative), our business rule says, that Name is mandatory and model can't be valid without this property (so, in the best conditions, it should not be even created)

  1. Use required keyword:
public class Cat
{
    public required string Name { get; set; }
}

So, it looks like the best (class can't be created without explicit init of Name field), but only for the first glance, because it's also 'syntax sugar', which uses only for compilation. So, when we map a property using automapper, we face with the same problem: object can be mapped without this property (or with null value from source object).

So, all of these approach only mask the problem (avoid warning compilation): object can be created with fake (default) value!

Any way to resolve this problem?

Thanks

2

There are 2 answers

4
Lamp On

If the property cannot be null, just put it in constructor, so there is no warning and must initialize the class with a valid value.

public class Cat
{
    public Cat(string name)
    {
        Name = name;
    }
    public string Name { get; set; }
}
4
Steve Py On

The null-ability warning is a compile-time warning to remind you to ensure that the property is initialized. IMHO initializing the value to something that is invalid to remove the warning is no better than just ignoring/disabling the warning entirely.

If you want to guard at runtime then you need to implement your code with such a guard, regardless of making the compiler happy. This can either be via update actions rather than setters, or explicit setters and not using auto-properties.

public string Name { get; private set; }

public void UpdateName(string name)
{      
    ArgumentException.ThrowIfNullOrEmpty(name, nameof(name));
    Name = value;
}

or

private string _name;
public string Name
{
    get => _name;
    set 
    {
        ArgumentException.ThrowIfNullOrEmpty(value, nameof(Name));
        _name = value;
    }
}

In both cases you should consider having a constructor that initializes all required properties at least, which will satisfy the compiler warning. When it comes to Entity Framework this warning can be a bit of a pain so the pattern I use is to have the constructor with all required fields, but then add a protected default constructor for EF to use, and use the #pragma disable / restore around it to avoid the warning.