What does private
access modifier for init only setter in C# mean? I usually make setter as private for most of the properties in my domain classes. With init
, does it matter?
The following seem to work without any problem, the compiler does not complain.
public class Point
{
public int X { get; private init; }
public int Y { get; private init; }
}
So how is the above different from the below. There is not private below.
public class Point
{
public int X { get; init; }
public int Y { get; init; }
}
CodePudding user response:
It affects where the setter can be called from, just like normal setters.
Consider this code:
public class Point
{
public int X { get; private init; }
public int Y { get; private init; }
}
class Program
{
static void Main()
{
var point = new Point { X = 10, Y = 20 };
}
}
That fails with two compile-time errors:
The property or indexer 'Point.X' cannot be used in this context because the set accessor is inaccessible
(and the equivalent for Y
).
The same initializer would be valid in the Point
class, because the set accessors are accessible there.
Likewise the code above would be valid without the private
part of the set accessors, because then they can be called from anywhere (as part of an object initializer).
CodePudding user response:
The init
keyword was added in c# 9.0 in order to add immutable properties on objects.
The problem we used to have is that if you have this object you could still modify the Name property (although it has a private setter) via a public method. for example:
public class Person
{
public Person(string name)
{
this.Name = name;
}
public void SetName(string name)
{
this.Name = name;
}
public string Name { get; private set; }
}
And we also couldn't use object initializers
var person = new Person
{
Name = "Jane Doe" // Compile Error
};
Now, if we change the code to use init
public class Person
{
public Person(string name)
{
this.Name = name;
}
public string Name { get; init; }
}
We are now able to use object initializers
var person = new Person
{
Name = "Jane Doe" // No error
};
But, if we use your private init
like your example
public class Person
{
public Person(string name)
{
this.Name = name;
}
public string Name { get; private init; }
}
We won't be able to do use object initializers
var person = new Person
{
Name = "Jane Doe" // Compile error
};