Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ A contextual keyword is used to provide a specific meaning in the code, but it i
|[dynamic](../builtin-types/reference-types.md)|Defines a reference type that enables operations in which it occurs to bypass compile-time type checking.|
|[get](./get.md)|Defines an accessor method for a property or an indexer.|
|[global](../operators/namespace-alias-qualifier.md)|Alias of the global namespace, which is otherwise unnamed.|
|[init](./init.md)|Defines an accessor method for a property or an indexer.|
|[partial](./partial-type.md)|Defines partial classes, structs, and interfaces throughout the same compilation unit.|
|[remove](./remove.md)|Defines a custom event accessor that is invoked when client code unsubscribes from the event.|
|[set](./set.md)|Defines an accessor method for a property or an indexer.|
Expand Down
36 changes: 36 additions & 0 deletions docs/csharp/language-reference/keywords/init.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
description: "init keyword - C# Reference"
title: "init keyword - C# Reference"
ms.date: 03/03/2021
f1_keywords:
- "init"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidwengier Do we need this? or only init_CSharpKeyword is sufficient?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Certainly don't need it from Roslyn's point of view.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@BillWagner The articles in the keywords folder have two entries under f1_keywords (sometimes in reverse order):

f1_keywords: 
  - "<keyword>_CSharpKeyword"
  - "<keyword>"

Is the second entry superfluous?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the second entry is superfluous. Ping @ghogen to verify.

- "init_CSharpKeyword"
helpviewer_keywords:
- "init keyword [C#]"
---
# 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).

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.

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

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

## C# language specification

[!INCLUDE[CSharplangspec](~/includes/csharplangspec-md.md)]

## See also

- [C# Reference](../index.md)
- [C# Programming Guide](../../programming-guide/index.md)
- [C# Keywords](index.md)
- [Properties](../../programming-guide/classes-and-structs/properties.md)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class InitExample
{
private double _seconds;

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

public double Seconds
{
get => _seconds;
init => _seconds = value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ ms.assetid: aa55fa97-ccec-431f-b5e9-5ac789fd32b7
---
# Auto-Implemented Properties (C# Programming Guide)

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

## Example

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

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

* Declare only a `get` accessor (immutable everywhere except the constructor).
* Declare a `get` accessor and an `init` accessor (immutable everywhere except during object construction).
* Declare the `set` accessor as [private](../../language-reference/keywords/private.md) (immutable to consumers).

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

## See also

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ ms.assetid: 1dc5a8ad-a4f7-4f32-8506-3fc6d8c8bfed

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.

You can make an immutable property in two ways:
You can make an immutable property in the following ways:

- 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.
- Declare only the [get](../../language-reference/keywords/get.md) accessor, which makes the property immutable everywhere except in the type's constructor.

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

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

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.
- You can declare only the [get](../../language-reference/keywords/get.md) accessor, which makes the property immutable everywhere except in the type's constructor.

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ A property is a member that provides a flexible mechanism to read, write, or com

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

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

- The [value](../../language-reference/keywords/value.md) keyword is used to define the value being assigned by the `set` accessor.
- The [value](../../language-reference/keywords/value.md) keyword is used to define the value being assigned by the `set` or `init` accessor.
- 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.

- 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).
Expand Down Expand Up @@ -48,7 +48,7 @@ The following example illustrates this pattern. In this example, the `TimePeriod

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.

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

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ms.assetid: f7f67b05-0983-4cdb-96af-1855d24c967c
---
# Using Properties (C# Programming Guide)

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

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.

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

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

## The get Accessor
## The get accessor

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`:

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

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

## The set Accessor
## The set accessor

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:

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

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

## The init accessor

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

## Remarks

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

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

Expand All @@ -71,13 +75,13 @@ A property overriding a virtual property can also be [sealed](../../language-ref
> [!NOTE]
> 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.

## Example
## Examples

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.

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

## Example
## Hidden property example

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:

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

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

## Example
## Override property example

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.

Expand Down
2 changes: 2 additions & 0 deletions docs/csharp/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,8 @@ items:
href: language-reference/keywords/add.md
- name: get
href: language-reference/keywords/get.md
- name: init
href: language-reference/keywords/init.md
- name: partial (Type)
href: language-reference/keywords/partial-type.md
- name: partial (Method)
Expand Down