Skip to content

Fixes #28385 #29925

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jun 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions docs/csharp/language-reference/keywords/init.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,30 @@ helpviewer_keywords:
---
# 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. For more information and examples, see [Properties](../../programming-guide/classes-and-structs/properties.md), [Auto-Implemented Properties](../../programming-guide/classes-and-structs/auto-implemented-properties.md), and [Indexers](../../programming-guide/indexers/index.md).
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.

For more information and examples, see [Properties](../../programming-guide/classes-and-structs/properties.md), [Auto-Implemented Properties](../../programming-guide/classes-and-structs/auto-implemented-properties.md), and [Indexers](../../programming-guide/indexers/index.md).

The following example defines both a `get` and an `init` accessor for a property named `Seconds`. It uses a private field named `_seconds` to back the property value.

[!code-csharp[init#1](snippets/InitExample1.cs)]

Often, the `init` accessor consists of a single statement that assigns a value, as it did in the previous example. You can implement the `init` accessor as an expression-bodied member. The following example implements both the `get` and the `init` accessors as expression-bodied members.
Often, the `init` accessor consists of a single statement that assigns a value, as it did in the previous example. Note that, because of `init`, the following will **not** work:

```csharp
var john = new Person_InitExample
{
YearOfBirth = 1984
};

john.YearOfBirth = 1926; //Not allowed, as it's value can only be set once in the constructor
```

The `init` accessor can be used as an expression-bodied member. Example:

[!code-csharp[init#3](snippets/InitExample3.cs)]

For simple cases in which a property's `get` and `init` accessors perform no other operation than setting or retrieving a value in a private backing field, you can take advantage of the C# compiler's support for auto-implemented properties. The following example implements `Hours` as an auto-implemented property.
The `init` accessor can also be used in auto-implemented properties as the following example code demonstrates:

[!code-csharp[init#2](snippets/InitExample2.cs)]

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
class InitExample
class Person_InitExample
{
private double _seconds;
private int _yearOfBirth;

public double Seconds
public int YearOfBirth
{
get { return _seconds; }
init { _seconds = value; }
get { return _yearOfBirth; }
init { _yearOfBirth = value; }
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class InitExampleAutoProperty
class Person_InitExampleAutoProperty
{
public double Hours { get; init; }
public int YearOfBirth { get; init; }
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
class InitExampleExpressionBodied
class Person_InitExampleExpressionBodied
{
private double _seconds;
private int _yearOfBirth;

public double Seconds
public int YearOfBirth
{
get => _seconds;
init => _seconds = value;
get => _yearOfBirth;
init => _yearOfBirth = value;
}
}