Skip to content

Commit 2f692b3

Browse files
authored
Document init accessor (#23082)
1 parent 491c280 commit 2f692b3

File tree

10 files changed

+91
-15
lines changed

10 files changed

+91
-15
lines changed

docs/csharp/language-reference/keywords/contextual-keywords.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ A contextual keyword is used to provide a specific meaning in the code, but it i
1818
|[dynamic](../builtin-types/reference-types.md)|Defines a reference type that enables operations in which it occurs to bypass compile-time type checking.|
1919
|[get](./get.md)|Defines an accessor method for a property or an indexer.|
2020
|[global](../operators/namespace-alias-qualifier.md)|Alias of the global namespace, which is otherwise unnamed.|
21+
|[init](./init.md)|Defines an accessor method for a property or an indexer.|
2122
|[partial](./partial-type.md)|Defines partial classes, structs, and interfaces throughout the same compilation unit.|
2223
|[remove](./remove.md)|Defines a custom event accessor that is invoked when client code unsubscribes from the event.|
2324
|[set](./set.md)|Defines an accessor method for a property or an indexer.|
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
description: "init keyword - C# Reference"
3+
title: "init keyword - C# Reference"
4+
ms.date: 03/03/2021
5+
f1_keywords:
6+
- "init"
7+
- "init_CSharpKeyword"
8+
helpviewer_keywords:
9+
- "init keyword [C#]"
10+
---
11+
# init (C# Reference)
12+
13+
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).
14+
15+
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.
16+
17+
[!code-csharp[init#1](snippets/InitExample1.cs)]
18+
19+
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.
20+
21+
[!code-csharp[init#3](snippets/InitExample3.cs)]
22+
23+
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.
24+
25+
[!code-csharp[init#2](snippets/InitExample2.cs)]
26+
27+
## C# language specification
28+
29+
[!INCLUDE[CSharplangspec](~/includes/csharplangspec-md.md)]
30+
31+
## See also
32+
33+
- [C# Reference](../index.md)
34+
- [C# Programming Guide](../../programming-guide/index.md)
35+
- [C# Keywords](index.md)
36+
- [Properties](../../programming-guide/classes-and-structs/properties.md)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class InitExample
2+
{
3+
private double _seconds;
4+
5+
public double Seconds
6+
{
7+
get { return _seconds; }
8+
init { _seconds = value; }
9+
}
10+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class InitExampleAutoProperty
2+
{
3+
public double Hours { get; init; }
4+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class InitExampleExpressionBodied
2+
{
3+
private double _seconds;
4+
5+
public double Seconds
6+
{
7+
get => _seconds;
8+
init => _seconds = value;
9+
}
10+
}

docs/csharp/programming-guide/classes-and-structs/auto-implemented-properties.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ ms.assetid: aa55fa97-ccec-431f-b5e9-5ac789fd32b7
99
---
1010
# Auto-Implemented Properties (C# Programming Guide)
1111

12-
In C# 3.0 and later, auto-implemented properties make property-declaration more concise when no additional logic is required in the property accessors. They also enable client code to create objects. When you declare a property as shown in the following example, the compiler creates a private, anonymous backing field that can only be accessed through the property's `get` and `set` accessors.
12+
In C# 3.0 and later, auto-implemented properties make property-declaration more concise when no additional logic is required in the property accessors. They also enable client code to create objects. When you declare a property as shown in the following example, the compiler creates a private, anonymous backing field that can only be accessed through the property's `get` and `set` accessors. In C# 9 and later, `init` accessors can also be declared as auto-implemented properties.
1313

1414
## Example
1515

@@ -25,7 +25,13 @@ In C# 6 and later, you can initialize auto-implemented properties similarly to f
2525
public string FirstName { get; set; } = "Jane";
2626
```
2727

28-
The class that is shown in the previous example is mutable. Client code can change the values in objects after creation. In complex classes that contain significant behavior (methods) as well as data, it's often necessary to have public properties. However, for small classes or structs that just encapsulate a set of values (data) and have little or no behaviors, you should either make the objects immutable by declaring the set accessor as [private](../../language-reference/keywords/private.md) (immutable to consumers) or by declaring only a get accessor (immutable everywhere except the constructor). For more information, see [How to implement a lightweight class with auto-implemented properties](./how-to-implement-a-lightweight-class-with-auto-implemented-properties.md).
28+
The class that is shown in the previous example is mutable. Client code can change the values in objects after creation. In complex classes that contain significant behavior (methods) as well as data, it's often necessary to have public properties. However, for small classes or structs that just encapsulate a set of values (data) and have little or no behaviors, you should use one of the following options for making the objects immutable:
29+
30+
* Declare only a `get` accessor (immutable everywhere except the constructor).
31+
* Declare a `get` accessor and an `init` accessor (immutable everywhere except during object construction).
32+
* Declare the `set` accessor as [private](../../language-reference/keywords/private.md) (immutable to consumers).
33+
34+
For more information, see [How to implement a lightweight class with auto-implemented properties](./how-to-implement-a-lightweight-class-with-auto-implemented-properties.md).
2935

3036
## See also
3137

docs/csharp/programming-guide/classes-and-structs/how-to-implement-a-lightweight-class-with-auto-implemented-properties.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,15 @@ ms.assetid: 1dc5a8ad-a4f7-4f32-8506-3fc6d8c8bfed
1313

1414
This example shows how to create an immutable lightweight class that serves only to encapsulate a set of auto-implemented properties. Use this kind of construct instead of a struct when you must use reference type semantics.
1515

16-
You can make an immutable property in two ways:
16+
You can make an immutable property in the following ways:
1717

18-
- You can declare the [set](../../language-reference/keywords/set.md) accessor to be [private](../../language-reference/keywords/private.md). The property is only settable within the type, but it is immutable to consumers.
18+
- Declare only the [get](../../language-reference/keywords/get.md) accessor, which makes the property immutable everywhere except in the type's constructor.
19+
20+
- Declare an [init](../../language-reference/keywords/init.md) accessor instead of a `set` accessor, which makes the property settable only in the constructor or by using an [object initializer](object-and-collection-initializers.md).
21+
22+
- Declare the [set](../../language-reference/keywords/set.md) accessor to be [private](../../language-reference/keywords/private.md). The property is settable within the type, but it is immutable to consumers.
1923

2024
When you declare a private `set` accessor, you cannot use an object initializer to initialize the property. You must use a constructor or a factory method.
21-
- You can declare only the [get](../../language-reference/keywords/get.md) accessor, which makes the property immutable everywhere except in the type's constructor.
2225

2326
The following example shows how a property with only get accessor differs than one with get and private set.
2427

docs/csharp/programming-guide/classes-and-structs/properties.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ A property is a member that provides a flexible mechanism to read, write, or com
1717

1818
- Properties enable a class to expose a public way of getting and setting values, while hiding implementation or verification code.
1919

20-
- A [get](../../language-reference/keywords/get.md) property accessor is used to return the property value, and a [set](../../language-reference/keywords/set.md) property accessor is used to assign a new value. These accessors can have different access levels. For more information, see [Restricting Accessor Accessibility](./restricting-accessor-accessibility.md).
20+
- A [get](../../language-reference/keywords/get.md) property accessor is used to return the property value, and a [set](../../language-reference/keywords/set.md) property accessor is used to assign a new value. In C# 9 and later, an [init](../../language-reference/keywords/init.md) property accessor is used to assign a new value only during object construction. These accessors can have different access levels. For more information, see [Restricting Accessor Accessibility](./restricting-accessor-accessibility.md).
2121

22-
- The [value](../../language-reference/keywords/value.md) keyword is used to define the value being assigned by the `set` accessor.
22+
- The [value](../../language-reference/keywords/value.md) keyword is used to define the value being assigned by the `set` or `init` accessor.
2323
- Properties can be *read-write* (they have both a `get` and a `set` accessor), *read-only* (they have a `get` accessor but no `set` accessor), or *write-only* (they have a `set` accessor, but no `get` accessor). Write-only properties are rare and are most commonly used to restrict access to sensitive data.
2424

2525
- Simple properties that require no custom accessor code can be implemented either as expression body definitions or as [auto-implemented properties](./auto-implemented-properties.md).
@@ -48,7 +48,7 @@ The following example illustrates this pattern. In this example, the `TimePeriod
4848

4949
In some cases, property `get` and `set` accessors just assign a value to or retrieve a value from a backing field without including any additional logic. By using auto-implemented properties, you can simplify your code while having the C# compiler transparently provide the backing field for you.
5050

51-
If a property has both a `get` and a `set` accessor, both must be auto-implemented. You define an auto-implemented property by using the `get` and `set` keywords without providing any implementation. The following example repeats the previous one, except that `Name` and `Price` are auto-implemented properties. Note that the example also removes the parameterized constructor, so that `SaleItem` objects are now initialized with a call to the parameterless constructor and an [object initializer](object-and-collection-initializers.md).
51+
If a property has both a `get` and a `set` (or a `get` and an `init`) accessor, both must be auto-implemented. You define an auto-implemented property by using the `get` and `set` keywords without providing any implementation. The following example repeats the previous one, except that `Name` and `Price` are auto-implemented properties. The example also removes the parameterized constructor, so that `SaleItem` objects are now initialized with a call to the parameterless constructor and an [object initializer](object-and-collection-initializers.md).
5252

5353
[!code-csharp[Properties#4](../../../../samples/snippets/csharp/programming-guide/classes-and-structs/properties-4.cs)]
5454

docs/csharp/programming-guide/classes-and-structs/using-properties.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ ms.assetid: f7f67b05-0983-4cdb-96af-1855d24c967c
1010
---
1111
# Using Properties (C# Programming Guide)
1212

13-
Properties combine aspects of both fields and methods. To the user of an object, a property appears to be a field, accessing the property requires the same syntax. To the implementer of a class, a property is one or two code blocks, representing a [get](../../language-reference/keywords/get.md) accessor and/or a [set](../../language-reference/keywords/set.md) accessor. The code block for the `get` accessor is executed when the property is read; the code block for the `set` accessor is executed when the property is assigned a new value. A property without a `set` accessor is considered read-only. A property without a `get` accessor is considered write-only. A property that has both accessors is read-write.
13+
Properties combine aspects of both fields and methods. To the user of an object, a property appears to be a field, accessing the property requires the same syntax. To the implementer of a class, a property is one or two code blocks, representing a [get](../../language-reference/keywords/get.md) accessor and/or a [set](../../language-reference/keywords/set.md) accessor. The code block for the `get` accessor is executed when the property is read; the code block for the `set` accessor is executed when the property is assigned a new value. A property without a `set` accessor is considered read-only. A property without a `get` accessor is considered write-only. A property that has both accessors is read-write. In C# 9 and later, you can use an `init` accessor instead of a `set` accessor to make the property read-only.
1414

1515
Unlike fields, properties are not classified as variables. Therefore, you cannot pass a property as a [ref](../../language-reference/keywords/ref.md) or [out](../../language-reference/keywords/out-parameter-modifier.md) parameter.
1616

@@ -24,7 +24,7 @@ In this example, `Month` is declared as a property so that the `set` accessor ca
2424

2525
Auto-implemented properties provide simplified syntax for simple property declarations. For more information, see [Auto-Implemented Properties](auto-implemented-properties.md).
2626

27-
## The get Accessor
27+
## The get accessor
2828

2929
The body of the `get` accessor resembles that of a method. It must return a value of the property type. The execution of the `get` accessor is equivalent to reading the value of the field. For example, when you are returning the private variable from the `get` accessor and optimizations are enabled, the call to the `get` accessor method is inlined by the compiler so there is no method-call overhead. However, a virtual `get` accessor method cannot be inlined because the compiler does not know at compile-time which method may actually be called at run time. The following is a `get` accessor that returns the value of a private field `_name`:
3030

@@ -46,7 +46,7 @@ The `get` accessor can be used to return the field value or to compute it and re
4646

4747
In the previous code segment, if you do not assign a value to the `Name` property, it will return the value `NA`.
4848

49-
## The set Accessor
49+
## The set accessor
5050

5151
The `set` accessor resembles a method whose return type is [void](../../language-reference/builtin-types/void.md). It uses an implicit parameter called `value`, whose type is the type of the property. In the following example, a `set` accessor is added to the `Name` property:
5252

@@ -58,9 +58,13 @@ When you assign a value to the property, the `set` accessor is invoked by using
5858

5959
It is an error to use the implicit parameter name, `value`, for a local variable declaration in a `set` accessor.
6060

61+
## The init accessor
62+
63+
The code to create an `init` accessor is the same as the code to create a `set` accessor except that you use the `init` keyword instead of `set`. The difference is that the `init` accessor can only be used in the constructor or by using an [object-initializer](object-and-collection-initializers.md).
64+
6165
## Remarks
6266

63-
Properties can be marked as `public`, `private`, `protected`, `internal`, `protected internal` or `private protected`. These access modifiers define how users of the class can access the property. The `get` and `set` accessors for the same property may have different access modifiers. For example, the `get` may be `public` to allow read-only access from outside the type, and the `set` may be `private` or `protected`. For more information, see [Access Modifiers](./access-modifiers.md).
67+
Properties can be marked as `public`, `private`, `protected`, `internal`, `protected internal`, or `private protected`. These access modifiers define how users of the class can access the property. The `get` and `set` accessors for the same property may have different access modifiers. For example, the `get` may be `public` to allow read-only access from outside the type, and the `set` may be `private` or `protected`. For more information, see [Access Modifiers](./access-modifiers.md).
6468

6569
A property may be declared as a static property by using the `static` keyword. This makes the property available to callers at any time, even if no instance of the class exists. For more information, see [Static Classes and Static Class Members](./static-classes-and-static-class-members.md).
6670

@@ -71,13 +75,13 @@ A property overriding a virtual property can also be [sealed](../../language-ref
7175
> [!NOTE]
7276
> It is an error to use a [virtual](../../language-reference/keywords/virtual.md), [abstract](../../language-reference/keywords/abstract.md), or [override](../../language-reference/keywords/override.md) modifier on an accessor of a [static](../../language-reference/keywords/static.md) property.
7377
74-
## Example
78+
## Examples
7579

7680
This example demonstrates instance, static, and read-only properties. It accepts the name of the employee from the keyboard, increments `NumberOfEmployees` by 1, and displays the Employee name and number.
7781

7882
[!code-csharp[csProgGuideProperties#2](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideProperties/CS/Properties.cs#2)]
7983

80-
## Example
84+
## Hidden property example
8185

8286
This example demonstrates how to access a property in a base class that is hidden by another property that has the same name in a derived class:
8387

@@ -95,7 +99,7 @@ The following are important points in the previous example:
9599

96100
For more information about hiding members, see the [new Modifier](../../language-reference/keywords/new-modifier.md).
97101

98-
## Example
102+
## Override property example
99103

100104
In this example, two classes, `Cube` and `Square`, implement an abstract class, `Shape`, and override its abstract `Area` property. Note the use of the [override](../../language-reference/keywords/override.md) modifier on the properties. The program accepts the side as an input and calculates the areas for the square and cube. It also accepts the area as an input and calculates the corresponding side for the square and cube.
101105

docs/csharp/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,6 +1152,8 @@ items:
11521152
href: language-reference/keywords/add.md
11531153
- name: get
11541154
href: language-reference/keywords/get.md
1155+
- name: init
1156+
href: language-reference/keywords/init.md
11551157
- name: partial (Type)
11561158
href: language-reference/keywords/partial-type.md
11571159
- name: partial (Method)

0 commit comments

Comments
 (0)