In new version of C# is default option nullable. I mean this

It's really good feature for me. But I don't understand one thing. Is property nullable by me or by program?
I know that this property should never be null because I fill it in the form and never set it as null. But in general it can be null. How should I mark it?
Example:
UserModel:
public string? Name { get; set; }
public string Name { get; set; } = null!
I'm really confused.
CodePudding user response:
Where a value can be null, and the <Nullable>enable</Nullable> value is set in your *.csproj file, you must declare those values as nullable.
In your given example, the nullable type (instead of assigning null as a default) is the way to go:
public string? Name {get; set;}
You'll also notice VS complaining at you with warnings every time you introduce a property etc which can be nullable, but isn't marked as such.
CodePudding user response:
I know that this property should never be null because I fill it in the form and never set it as null. But in general it can be null. How should I mark it?
If it is set to non-null in the constructor, then you can declare it a string rather than string? because it really is guaranteed to never be null.
If, however, it is null after the constructor has run (and before any other methods are called) then it CAN be null and you should declare it as string?.
The dichotomy you face is that (from what you say) it should never be null when the class is used correctly - i.e. if the calling code does indeed call the method that initialises the property to non-null before accessing it, it will be guaranteed to be not null - which means you would like to declare it as a non-null string so that callers don't need to use the null-forgiving ! operator to suppress nullable warnings.
What to do in this case? Well I think you have three possibilities:
- Declare the property as nullable:
string?and let the callers suppress the nullable warning or check the value for null. - Initialise the property to a non-null default such as
string.Emptyand declare the property as non nullablestring. - Assume that accessing the property when it is null is a programming error, and throw an appropriate exception.
For the last case, you could do something like this:
private string? _name;
public string Name
{
get
{
if (_name == null)
throw new InvalidOperationException("Do not access Name without setting it to non-null or calling Init()");
return _name;
}
set
{
if (value == null)
throw new ArgumentNullException("value", "You cannot set Name to null.");
_name = value;
}
}
This assumes that there's a method called Init() that can be called to initialise Name, but of course your code may vary.
Regardless of which of those approaches you take, you should really check for null in the property setter, as shown above.
Note that a more succinct way of writing the setter null check is:
set
{
_name = value ?? throw new ArgumentNullException("value", "You cannot set Name to null.");
}
