Init + private set accessors on the same property?

穿精又带淫゛_ 提交于 2020-12-12 06:49:54

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!