I have this code
#enable nullable
public class SomeClass
{
public string SomeProperty { get; init; }
}
With the following compiler error:
[CS8618] Non-nullable property 'SomeProperty' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
I thought the whole point of declaring the property as init was to ensure the properties are set at creation time with the property initializer syntax, like
var s = new SomeClass { SomeProperty = "some value" };
So why do I get this compiler warning? Have I completely misunderstood what the init
is for?
CodePudding user response:
An init-only property doesn't require that properties are set at creation time with the property initializer syntax. It allows them to be set that way instead of requiring that all read-only properties are set by constructors.
So with your code,
var s = new SomeClass();
... is still perfectly valid, and would end up with s.SomeProperty
being null, contrary to the nullability of its type.
CodePudding user response:
with init keyword the property value can only be changed in constructor or initilize block.
if you use the default constructor
var s = new SomeClass ();
s.SomeProperty = "A value";//Compiler error CS8852 Init-only property or indexer "SomeClass.SomeProperty" can only be assigned in an object initializer, or on "this" or "base" in an instance constructor or an "init" accessor.
The property SomeProperty was initialized with null, but is not nullable reference type. the compiler is reporting a possible future runtime error. Warning CS8618 Non-nullable property "SomeProperty" must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
If there is no problem that this happens, the warning can be removed with the following
1. Use null forgiving operator
public class SomeClass
{
public string SomeProperty { get; init; } = null!;// indicating null value is a correct not null value.
}
When you try to access and use the SomeProperty value, you need to check nullability to avoid a null reference exception even though the type indicates that it is non-nullable. This is irritating.
if(s.SomeProperty==null) //OK
{
//DO SOME STUFF
}
var length = s.SomeProperty?.Length ?? 0; //OK
var length2 = s.SomeProperty;//NullReferenceException
2. Assigning/Initialize a valid value for property
public class SomeClass
{
public string SomeProperty { get; init; } = "My initial value";
}
you can invoke default constructor without initialze the property
var s = new SomeClass (); //Some property is "My initial value"
or invoke constructor with initialization block
var s = new SomeClass()
{
SomeProperty = "My new intial value"
};
var length = s.SomeProperty.Length; //NO exception / No problem