Search code examples
c#.net-6.0nullable

Null behavior in .NET 6.0


I'm wondering about the correct way to deal with a warning I'm see in VS2022 in a .net 6.0 project. I have the initialization for a class done in a separate method, i.e. not directly in the constructor. But I get a warning saying: Non-nullable field 'Name' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

I don't want the Name field to be nullable, in other words, an instance of this class should always have a value for Name. And the Init() method gets called from both constructors and sets this value. If it helps, the warning number is CS8618.

There seems to be more than one solution to this, but what is the correct way to get rid of this warning ? I'd like to avoid having #pragma ignore warning ugliness in my code, so I wouldn't consider this a valid solution for me.

class ClassA {
  public string Name;

  public ClassA(int i) { 
    Init(i.ToString());
  }
  public ClassA(string s) {
    Init(s);
  }
  private void Init(string id) {
     Name = id;
     //lots of other stuff happening in this method
  } 
}

Solution

  • You should not ignore nullability warnings whenever it is possible. In this particular case you can use MemberNotNullAttribute to help the compiler:

    Specifies that the method or property will ensure that the listed field and property members have values that aren't null.

    public class ClassA
    {
        public string Name;
    
        public ClassA(int i)
        {
            Init(i.ToString());
        }
    
        public ClassA(string s)
        {
            Init(s);
        }
    
        [MemberNotNull(nameof(Name))]
        private void Init(string id)
        {
            Name = id;
        }
    }
    

    For other useful nullability analysis attribute - see this doc.

    Or use approach suggested by @Panagiotis Kanavos in comments - use constructor chaining:

    public class ClassA
    {
        public string Name;
    
        public ClassA(int i) : this(i.ToString())
        {
        }
    
        public ClassA(string s)
        {
            Name = s;
        }
    }
    

    Also note that usually it is recommended to encapsulate fields into properties.