Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Init + private set accessors on the same property?

Tags:

c#

c#-9.0

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?

like image 475
Gábor Imre Avatar asked Nov 11 '20 09:11

Gábor Imre


People also ask

What is INIT in property?

init (C# Reference) In C# 9 and later, the init keyword defines an accessor method in a property or indexer. An init-only setter assigns a value to the property or the indexer element only during object construction. This enforces immutability, so that once the object is initialized, it can't be changed again.

What is the difference between set and private set?

Setter pass user-specified values from page markup to a controller. Any setter methods in a controller are automatically executed before any action methods. Private setter means the variable can be set inside the class in which it is declared in. It will behave like readonly property outside that class's scope.

What are accessors in C#?

A get property accessor is used to return the property value, and a set property accessor is used to assign a new value. In C# 9 and later, an init property accessor is used to assign a new value only during object construction. These accessors can have different access levels.

What does init do?

The git init command creates a new Git repository. It can be used to convert an existing, unversioned project to a Git repository or initialize a new, empty repository.


1 Answers

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)
like image 101
TJ Rockefeller Avatar answered Oct 05 '22 06:10

TJ Rockefeller