简体   繁体   中英

Init + private set accessors on the same property?

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?

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)

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
}

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..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM