Skip to content

Consolidated ref field reference #35900

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 1 commit into from
Jun 21, 2023
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
24 changes: 19 additions & 5 deletions docs/csharp/language-reference/builtin-types/ref-struct.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,30 @@ You can apply the `readonly` modifier to a `ref` field in the following ways:
- `ref readonly`: At any point, you cannot assign a value with the `=` operator to such a field. However, you can ref reassign a field with the `= ref` operator.
- `readonly ref readonly`: You can only ref reassign such a field in a constructor or an `init` accessor. At any point, you cannot assign a value to the field.

The compiler ensures that a reference stored in a `ref` field doesn't outlive the value to which it refers. For information about the scope rules, see the [Scope of references and values](../keywords/method-parameters.md#scope-of-references-and-values) section of the [Method parameters](../keywords/method-parameters.md) article.
The compiler ensures that a reference stored in a `ref` field doesn't outlive its referent.

The `ref` fields feature enables a safe implementation of types like <xref:System.Span%601?displayProperty=fullName>:

```csharp
public readonly ref struct Span<T>
{
internal readonly ref T _reference;
private readonly int _length;

// Omitted for brevity...
}
```

The `Span<T>` type stores a reference through which it accesses the contiguous elements in memory. The use of a reference enables a `Span<T>` instance to avoid copying the storage it refers to.

## C# language specification

For more information, see the [Structs](~/_csharpstandard/standard/structs.md) section of the [C# language specification](~/_csharpstandard/standard/README.md).
For more information, see the following sections of the [C# language specification](~/_csharpstandard/standard/README.md):

For more information about features introduced in C# 7.2 and later, see the following feature proposal notes:
- [Structs: Ref modifier](~/_csharpstandard/standard/structs.md#1623-ref-modifier)
- [Safe context constraint for ref struct types](~/_csharpstandard/standard/structs.md#16412-safe-context-constraint-for-ref-struct-types)

- [C# 7.2 - Compile-time safety for ref-like types](~/_csharplang/proposals/csharp-7.2/span-safety.md)
- [C# 11 - ref fields and scoped](~/_csharplang/proposals/csharp-11.0/low-level-struct-improvements.md)
For more information about `ref` fields, see the [Low-level struct improvements](~/_csharplang/proposals/csharp-11.0/low-level-struct-improvements.md) proposal note.

## See also

Expand Down
20 changes: 2 additions & 18 deletions docs/csharp/language-reference/keywords/ref.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ You use the `ref` keyword in the following contexts:
- In a method signature, to return a value to the caller by reference. For more information, see [Reference return values](#reference-return-values).
- In a declaration of a local variable, to declare a reference variable. For more information, see the [Reference variables](../statements/declarations.md#reference-variables) section of the [Declaration statements](../statements/declarations.md) article.
- As the part of a [conditional ref expression](../operators/conditional-operator.md#conditional-ref-expression) or a [ref assignment operator](../operators/assignment-operator.md#ref-assignment).
- In a `struct` declaration, to declare a `ref struct`. For more information, see the [`ref struct`](../builtin-types/ref-struct.md) article.
- In a `ref struct` declaration, to declare that a field is a reference. See the [`ref` field](../builtin-types/ref-struct.md) article.
- In a `struct` declaration, to declare a `ref struct`. For more information, see the [`ref` structure types](../builtin-types/ref-struct.md) article.
- In a `ref struct` definition, to declare a `ref` field. For more information, see the [`ref` fields](../builtin-types/ref-struct.md#ref-fields) section of the [`ref` structure types](../builtin-types/ref-struct.md) article.

## Passing an argument by reference

Expand Down Expand Up @@ -111,22 +111,6 @@ When the caller stores the value returned by the `GetBookByTitle` method as a re

:::code language="csharp" source="snippets/RefParameterModifier.cs" id="Snippet5":::

## ref fields

In [`ref struct`](../builtin-types/ref-struct.md) types, you can declare fields that are `ref` fields. `ref` fields are valid only in `ref struct` types to ensure the reference doesn't outlive the object it refers to. This feature enables types like <xref:System.Span%601?displayProperty=fullName>:

```csharp
public readonly ref struct Span<T>
{
internal readonly ref T _reference;
private readonly int _length;

// Omitted for brevity...
}
```

The `Span<T>` type stores a reference through which it accesses the consecutive elements. A reference enables the `Span<T>` object to avoid making copies of the storage it refers to.

## C# language specification

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