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
4 changes: 4 additions & 0 deletions .openpublishing.redirection.json
Original file line number Diff line number Diff line change
Expand Up @@ -2029,6 +2029,10 @@
{
"source_path":"docs/standard/serialization/web-services-ixmlserializable-technology-sample.md",
"redirect_url":"/previous-versions/dotnet/netframework-4.0/h2byscsb(v=vs.100)"
},
{
"source_path":"docs/csharp/reference-semantics-with-value-types.md",
"redirect_url":"/dotnet/csharp/write-safe-efficient-code"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,4 @@ You can't use the `in`, `ref`, and `out` keywords for the following kinds of met
- [C# Programming Guide](../../programming-guide/index.md)
- [C# Keywords](index.md)
- [Method Parameters](method-parameters.md)
- [Reference Semantics with Value Types](../../reference-semantics-with-value-types.md)
- [Write safe efficient code](../../write-safe-efficient-code.md)
29 changes: 27 additions & 2 deletions docs/csharp/language-reference/keywords/ref.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ The `ref` keyword indicates a value that is passed by reference. It is used in f
- In a method signature and in a method call, to pass an argument to a method by reference. See [Passing an argument by reference](#passing-an-argument-by-reference) for more information.
- In a method signature, to return a value to the caller by reference. See [Reference return values](#reference-return-values) for more information.
- In a member body, to indicate that a reference return value is stored locally as a reference that the caller intends to modify or, in general, a local variable accesses another value by reference. See [Ref locals](#ref-locals) for more information.
- In a `struct` declaration to declare a `ref struct` or a `ref readonly struct`. For more information, see [Reference semantics with value types](../../reference-semantics-with-value-types.md).
- In a `struct` declaration to declare a `ref struct` or a `ref readonly struct`. For more information see [ref struct types](#ref-struct-types).


## Passing an argument by reference

Expand Down Expand Up @@ -83,6 +84,8 @@ return ref DecimalArray[0];

In order for the caller to modify the object's state, the reference return value must be stored to a variable that is explicitly defined as a [ref local](#ref-locals).

The called method may also declare the return value as `ref readonly` to return the value by reference, and enforce that the calling code cannot modify the returned value. The calling method can avoid copying the returned valued by storing the value in a local [ref readonly](#ref-readonly-local) variable.

For an example, see [A ref returns and ref locals example](#a-ref-returns-and-ref-locals-example)

## Ref locals
Expand All @@ -105,6 +108,10 @@ ref VeryLargeStruct reflocal = ref veryLargeStruct;

Note that in both examples the `ref` keyword must be used in both places, or the compiler generates error CS8172, "Cannot initialize a by-reference variable with a value."

## ref readonly locals

A ref readonly local is used to refer to values returned using `return readonly ref`. A `ref readonly` variable combines the properties of a `ref` local variable with a `readonly` variable: it is an alias to the storage it's assigned to, and it cannot be modified.

## A ref returns and ref locals example

The following example defines a `Book` class that has two <xref:System.String> fields, `Title` and `Author`. It also defines a `BookCollection` class that includes a private array of `Book` objects. Individual book objects are returned by reference by calling its `GetBookByTitle` method.
Expand All @@ -115,13 +122,31 @@ When the caller stores the value returned by the `GetBookByTitle` method as a re

[!code-csharp[csrefKeywordsMethodParams#6](~/samples/snippets/csharp/language-reference/keywords/in-ref-out-modifier/RefParameterModifier.cs#5)]

## Ref struct types

Adding the `ref` modifier to a `struct` declaration defines that instances of that type must be stack allocated. In other words, instances of these types can never be created on the
heap as a member of another class. The primary motivation for this feature was <xref:System.Span%601> and related structures.

The goal of keeping a `ref struct` type as a stack-allocated variable introduces several rules that the compiler enforces for all `ref struct` types.
Copy link
Contributor

Choose a reason for hiding this comment

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

Difficult to comprehend. What about:

Because instances of a ref struct type can be only stack-allocated, you cannot use them in the following scenarios:


- You can't box a `ref struct`. You cannot assign a `ref struct` type to a variable of type `object`, `dynamic`, or any interface type.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it worth to mention here (as a consequence): "ref struct type cannot implement interfaces"?

- `ref struct` types cannot implement interfaces.
- You can't declare a `ref struct` as a member of a class or a normal struct.
- You cannot declare local variables that are `ref struct` types in async methods. You can declare them in synchronous methods that return <xref:System.Threading.Tasks.Task>, <xref:System.Threading.Tasks.Task%601> or `Task`-like types.
- You cannot declare `ref struct` local variables in iterators.
- You cannot capture `ref struct` variables in lambda expressions or local functions.

These restrictions ensure you don't accidentally use a `ref struct` in a manner that could promote it to the managed heap.

You can combine modifiers to declare a struct as `readonly ref`. A `readonly ref struct` combines the benefits and restrictions of `ref struct` and `readonly struct` declarations.

## C# language specification

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

## See also

- [Reference semantics with value types](../../reference-semantics-with-value-types.md)
- [Write safe efficient code](../../write-safe-efficient-code.md)
- [Passing Parameters](../../programming-guide/classes-and-structs/passing-parameters.md)
- [Method Parameters](method-parameters.md)
- [C# Reference](../index.md)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,4 @@ closer to the end of the array.
## See also

- [ref keyword](../../language-reference/keywords/ref.md)
- [Reference Semantics with Value Types](../../../csharp/reference-semantics-with-value-types.md)
- [Write safe efficient code](../../../csharp/write-safe-efficient-code.md)
239 changes: 0 additions & 239 deletions docs/csharp/reference-semantics-with-value-types.md

This file was deleted.

Loading