问题
Is it possible to use a public init accessor and a private setter on the same property?
Currently I get error CS1007 "Property accessor already defined".
public record Stuff
{
public int MyProperty { get; init; private set; } // Error
public void SetMyProperty(int value) => MyProperty = value;
}
var stuff = new Stuff
{
MyProperty = 3, // Using the init accessor
};
stuff.SetMyProperty(4); // Using the private setter (indirectly)
My best guess would be to use a private member variable, a property for that variable with get
and init
accessors (not auto-implemented) and the setter member function. Can it be done more easily?
回答1:
Similar to specifying a constructor to initialize your value, you can use a private backing field so that you can still take advantage of the init logic and allow initialization without a specific constructor
public record Stuff
{
private int _myProperty;
public int MyProperty { get => _myProperty; init => _myProperty = value; }
public void SetMyProperty(int value) => _myProperty = value;
}
var stuff = new Stuff
{
MyProperty = 3 // Using the init accessor
};
stuff.SetMyProperty(4); // Using the private setter (indirectly)
回答2:
No you can not. The init keyword was added in an attempt to make immutable properties on objects.
So if you have the record:
public record Stuff
{
public int MyProperty { get; init; } // This can not be changed after initialization
}
MyProperty
can only be set during the initialization of your record.
If you want your property to be mutable then you use the set
accessor instead of init
.
public record Stuff
{
public int MyProperty { get; set; } // This can
}
回答3:
As @Jerry's answer you can not use both setters. That is to do with the mutability of the record/object.
If you want to have private set
ers and some initialization logic also, the way I use is constructors:
public record Stuff
{
public Stuff(int myProperty)
{
MyProperty = myProperty;
}
public int MyProperty { get; private set; }
public void SetMyProperty(int value) => MyProperty = value;
}
var stuff = new Stuff(3);
stuff.SetMyProperty(4);
It is all about domain requirements.
- Does
Stuff.MyProperty
needs to be publicly modifiable? - If it is, what would be the default value of that property, when Stuff instance is initialized? Does domain expects a default value?
etc..
来源:https://stackoverflow.com/questions/64783995/init-private-set-accessors-on-the-same-property