Reputation: 111
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
}
}
Upvotes: 2
Views: 4078
Reputation: 4983
Since only a single value is being set, why not do it in the constructor? Regardless, the solution is simple. Provide a default value.
Option 1:
public string Name { get; set; } = string.Empty;
Option 2:
private string _name = String.Empty;
public string Name
{
get { return _name; }
set { _name = value; }
}
Option 3:
private string _name = String.Empty;
public string Name
{
get => _name;
set => _name = value;
}
According to Nullable reference types:
Prior to C# 8.0, all reference types were nullable.
According to Default values of C# types (C# reference):
and according to Reference types (C# Reference)
C# also provides the following built-in reference types:
- dynamic
- object
- string
In .NET Framework 4.8, the following is permissible:
public string Name { get; set; } = null;
However, in .NET 6, this results in the following warning: warning CS8625: Cannot convert null literal to non-nullable reference type.
In .NET 6, one needs to specify a default (non-null) value - String.Empty can be used.
public string Name { get; set; } = string.Empty;
In .NET 6, if one would like to allow a null value for a String
, do the following:
public string? Name { get; set; } = null;
Resources:
Upvotes: 0
Reputation: 3882
You could also use a get-only-property
for your property.
public class ClassA
{
public string Name { get; }
public ClassA(int i)
{
Name = i.ToString();
}
public ClassA(string s)
{
Name = s ?? string.Empty;
}
}
Upvotes: 3
Reputation: 142008
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.
Upvotes: 1