C
C#6mo ago
KelTi

"Non-nullable field..." warning even though the value is ensured to be declared

Hi, I am very much a C# beginner so please excuse me if it's a dumb question. I'm learning from the Pro C# book and I have this code:
c#
class Employee
{
private string _empName;

public Employee(string name) /*Non-nullable field '_empName' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.*/
{
Name = name;
}

public string Name
{
get { return _empName; }
set
{
if (value?.Length > 15)
{
Console.WriteLine("Error! Name cannot exceed 15 characters");
_empName = String.Empty;
}
else
{
_empName = value ?? String.Empty;
}
}
}
}
c#
class Employee
{
private string _empName;

public Employee(string name) /*Non-nullable field '_empName' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.*/
{
Name = name;
}

public string Name
{
get { return _empName; }
set
{
if (value?.Length > 15)
{
Console.WriteLine("Error! Name cannot exceed 15 characters");
_empName = String.Empty;
}
else
{
_empName = value ?? String.Empty;
}
}
}
}
The question is - why am I seeing this warning? Inside the property "Name" I'm handling both cases - when the value is null and is not null. In both cases, I'm assigning some string value to the variable _empName, ensuring it doesn't end up as null. If I changed the _empName declaration to "private string _empName = String.Empty" then the warning goes away. I just don't see the need for that since I've already handled the null-case. Is that the desired behavior of the compiler? Why? Thanks for all the help in advance.
5 Replies
Angius
Angius6mo ago
_empName is neither initialized there, nor from the constructor Nothing else is guaranteed to run If the user never sets the Name property, the _empName will be uninitialized
KelTi
KelTiOP6mo ago
I skipped some code for brevity. That's what all of my constructors look like:
c#
public Employee() : this("", -1, 0, 0) { }

public Employee(string name, int id, float pay) : this(name, id, pay, 0) { }
c#
public Employee() : this("", -1, 0, 0) { }

public Employee(string name, int id, float pay) : this(name, id, pay, 0) { }
So you can see, it will be some string value in every case, even if the user opts for the default constructor. The other variables are irrelevant in this case
Angius
Angius6mo ago
Assuming the final constructor in the chain has a body, then sure Unless you're setting the property The compiler isn't smart enough to figure out that layer of indirectness
KelTi
KelTiOP6mo ago
Here's the final constructor:
c#
public Employee(string name, int id, float pay, int age)
{
Name = name;
ID = id;
Pay = pay;
Age = age;
}
c#
public Employee(string name, int id, float pay, int age)
{
Name = name;
ID = id;
Pay = pay;
Age = age;
}
Got it, so the code is safe but the compiler just isn't smart enough to figure that out. Thought so. Thank you for your answer What would be the "industry standard" in that situation? Do I initialize the _empName as String.Empty or declare it as nullable with "string?"?
Angius
Angius6mo ago
Initialize it with empty probably, yeah
Want results from more Discord servers?
Add your server