Skip to content
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

ref fields and scoped. Modify pages on struct creation, variable declaration, and ref struct. #30912

Merged
merged 16 commits into from
Sep 20, 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
26 changes: 25 additions & 1 deletion .openpublishing.redirection.csharp.json
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@
},
{
"source_path_from_root": "/docs/csharp/getting-started/whats-new.md",
"redirect_url": "/dotnet/csharp/whats-new/csharp-10"
"redirect_url": "/dotnet/csharp/whats-new/csharp-11"
},
{
"source_path_from_root": "/docs/csharp/getting-started/with-visual-studio-2017.md",
Expand Down Expand Up @@ -735,6 +735,10 @@
"source_path_from_root": "/docs/csharp/language-reference/keywords/value-types.md",
"redirect_url": "/dotnet/csharp/language-reference/builtin-types/value-types"
},
{
"source_path_from_root": "/docs/csharp/language-reference/keywords/var.md",
"redirect_url": "/dotnet/csharp/language-reference/statements/declarations#var"
},
{
"source_path_from_root": "/docs/csharp/language-reference/keywords/void.md",
"redirect_url": "/dotnet/csharp/language-reference/builtin-types/void"
Expand Down Expand Up @@ -1056,6 +1060,10 @@
"source_path_from_root": "/docs/csharp/programming-guide/classes-and-structs/how-to-access-a-collection-class-with-foreach.md",
"redirect_url": "/dotnet/csharp/language-reference/statements/iteration-statements"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/classes-and-structs/how-to-know-the-difference-passing-a-struct-and-passing-a-class-to-a-method.md",
"redirect_url": "/dotnet/csharp/language-reference/keywords/method-parameters"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/classes-and-structs/index.md",
"redirect_url": "/dotnet/csharp/fundamentals/object-oriented"
Expand All @@ -1068,6 +1076,18 @@
"source_path_from_root": "/docs/csharp/programming-guide/classes-and-structs/objects.md",
"redirect_url": "/dotnet/csharp/fundamentals/object-oriented/objects"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/classes-and-structs/passing-parameters.md",
"redirect_url": "/dotnet/csharp/language-reference/keywords/method-parameters"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/classes-and-structs/passing-reference-type-parameters.md",
"redirect_url": "/dotnet/csharp/language-reference/keywords/method-parameters"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/classes-and-structs/passing-value-type-parameters.md",
"redirect_url": "/dotnet/csharp/language-reference/keywords/method-parameters"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/classes-and-structs/polymorphism.md",
"redirect_url": "/dotnet/csharp/fundamentals/object-oriented/polymorphism"
Expand All @@ -1076,6 +1096,10 @@
"source_path_from_root": "/docs/csharp/programming-guide/classes-and-structs/records.md",
"redirect_url": "/dotnet/csharp/fundamentals/types/records"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/classes-and-structs/ref-returns.md",
"redirect_url": "/dotnet/csharp/language-reference/statements/declarations"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/classes-and-structs/structs.md",
"redirect_url": "/dotnet/csharp/language-reference/builtin-types/struct"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The exceptions thrown when calling reflection invoke APIs have changed.

## Previous behavior

- Previously, when an invoked method that [returns a value by reference](../../../../csharp/programming-guide/classes-and-structs/ref-returns.md) returned `null`, a <xref:System.NullReferenceException> was thrown.
- Previously, when an invoked method that [returns a value by reference](../../../../csharp/language-reference/statements/jump-statements.md#ref-returns) returned `null`, a <xref:System.NullReferenceException> was thrown.

- For constructors, the following exceptions were thrown:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ The following sections describe practices that the C# team follows to prepare co

:::code language="csharp" source="./snippets/coding-conventions/program.cs" id="Snippet8":::

- Don't use [var](../../language-reference/keywords/var.md) when the type is not apparent from the right side of the assignment. Don't assume the type is clear from a method name. A variable type is considered clear if it's a `new` operator or an explicit cast.
- Don't use [var](../../language-reference/statements/declarations.md#implicitly-typed-local-variables) when the type is not apparent from the right side of the assignment. Don't assume the type is clear from a method name. A variable type is considered clear if it's a `new` operator or an explicit cast.

:::code language="csharp" source="./snippets/coding-conventions/program.cs" id="Snippet9":::

Expand Down
2 changes: 1 addition & 1 deletion docs/csharp/fundamentals/object-oriented/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ You can "extend" a class without creating a derived class by creating a separate

## Implicitly Typed Local Variables

Within a class or struct method, you can use implicit typing to instruct the compiler to determine a variable's type at compile time. For more information, see [var (C# reference)](../../language-reference/keywords/var.md).
Within a class or struct method, you can use implicit typing to instruct the compiler to determine a variable's type at compile time. For more information, see [var (C# reference)](../../language-reference/statements/declarations.md#implicitly-typed-local-variables).

## Records

Expand Down
2 changes: 1 addition & 1 deletion docs/csharp/fundamentals/types/anonymous-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ If you don't specify member names in the anonymous type, the compiler gives the
> [!TIP]
> You can use .NET style rule [IDE0037](../../../fundamentals/code-analysis/style-rules/ide0037.md) to enforce whether inferred or explicit member names are preferred.

Typically, when you use an anonymous type to initialize a variable, you declare the variable as an implicitly typed local variable by using [var](../../language-reference/keywords/var.md). The type name cannot be specified in the variable declaration because only the compiler has access to the underlying name of the anonymous type. For more information about `var`, see [Implicitly Typed Local Variables](../../programming-guide/classes-and-structs/implicitly-typed-local-variables.md).
Typically, when you use an anonymous type to initialize a variable, you declare the variable as an implicitly typed local variable by using [var](../../language-reference/statements/declarations.md#implicitly-typed-local-variables). The type name cannot be specified in the variable declaration because only the compiler has access to the underlying name of the anonymous type. For more information about `var`, see [Implicitly Typed Local Variables](../../programming-guide/classes-and-structs/implicitly-typed-local-variables.md).

You can create an array of anonymously typed elements by combining an implicitly typed local variable and an implicitly typed array, as shown in the following example.

Expand Down
4 changes: 2 additions & 2 deletions docs/csharp/fundamentals/types/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ The compiler embeds the type information into the executable file as metadata. T

## Specifying types in variable declarations

When you declare a variable or constant in a program, you must either specify its type or use the [`var`](../../language-reference/keywords/var.md) keyword to let the compiler infer the type. The following example shows some variable declarations that use both built-in numeric types and complex user-defined types:
When you declare a variable or constant in a program, you must either specify its type or use the [`var`](../../language-reference/statements/declarations.md#implicitly-typed-local-variables) keyword to let the compiler infer the type. The following example shows some variable declarations that use both built-in numeric types and complex user-defined types:

:::code language="csharp" source="../../programming-guide/types/snippets/index/Program.cs" ID="Declarations":::

Expand Down Expand Up @@ -150,7 +150,7 @@ The use of the type parameter makes it possible to reuse the same class to hold

## Implicit types, anonymous types, and nullable value types

You can implicitly type a local variable (but not class members) by using the [`var`](../../language-reference/keywords/var.md) keyword. The variable still receives a type at compile time, but the type is provided by the compiler. For more information, see [Implicitly Typed Local Variables](../../programming-guide/classes-and-structs/implicitly-typed-local-variables.md).
You can implicitly type a local variable (but not class members) by using the [`var`](../../language-reference/statements/declarations.md#implicitly-typed-local-variables) keyword. The variable still receives a type at compile time, but the type is provided by the compiler. For more information, see [Implicitly Typed Local Variables](../../programming-guide/classes-and-structs/implicitly-typed-local-variables.md).

It can be inconvenient to create a named type for simple sets of related values that you don't intend to store or pass outside method boundaries. You can create *anonymous types* for this purpose. For more information, see [Anonymous Types](anonymous-types.md).

Expand Down
1 change: 0 additions & 1 deletion docs/csharp/how-to/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ In the How to section of the C# Guide, you can find quick answers to common ques
There are several tips and tricks that are common C# developer practices:

- [Initialize objects using an object initializer](../programming-guide/classes-and-structs/how-to-initialize-objects-by-using-an-object-initializer.md).
- [Learn the differences between passing a struct and a class to a method](../programming-guide/classes-and-structs/how-to-know-the-difference-passing-a-struct-and-passing-a-class-to-a-method.md).
- [Use operator overloading](../language-reference/operators/operator-overloading.md).
- [Implement and call a custom extension method](../programming-guide/classes-and-structs/how-to-implement-and-call-a-custom-extension-method.md).
- [Create a new method for an `enum` type using extension methods](../programming-guide/classes-and-structs/how-to-create-a-new-method-for-an-enumeration.md).
Expand Down
39 changes: 39 additions & 0 deletions docs/csharp/language-reference/builtin-types/ref-struct.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
title: "Ref Struct types - C# reference"
description: Learn about the ref struct type in C#
ms.date: 09/15/2022
---
# `ref` Structure types (C# reference)

Beginning with C# 7.2, you can use the `ref` modifier in the declaration of a value type. Instances of a `ref struct` type are allocated on the stack and can't escape to the managed heap. To ensure that, the compiler limits the usage of `ref struct` types as follows:

- A `ref struct` can't be the element type of an array.
- A `ref struct` can't be a declared type of a field of a class or a non-`ref struct`.
- A `ref struct` can't implement interfaces.
- A `ref struct` can't be boxed to <xref:System.ValueType?displayProperty=nameWithType> or <xref:System.Object?displayProperty=nameWithType>.
- A `ref struct` can't be a type argument.
- A `ref struct` variable can't be captured by a [lambda expression](../operators/lambda-expressions.md) or a [local function](../../programming-guide/classes-and-structs/local-functions.md).
- A `ref struct` variable can't be used in an [`async`](../keywords/async.md) method. However, you can use `ref struct` variables in synchronous methods, for example, in methods that return <xref:System.Threading.Tasks.Task> or <xref:System.Threading.Tasks.Task%601>.
- A `ref struct` variable can't be used in [iterators](../../iterators.md).

Beginning with C# 8.0, you can define a disposable `ref struct`. To do that, ensure that a `ref struct` fits the [disposable pattern](~/_csharplang/proposals/csharp-8.0/using.md#pattern-based-using). That is, it has an instance or extension `Dispose` method, which is accessible, parameterless and has a `void` return type.

Beginning with C# 11.0, a `ref struct` may contain `ref` fields. A `ref` field may be assigned or reassigned to refer to another object. Ref fields are declared using the same syntax as [`ref` local variables](../statements/declarations.md#ref-locals). The compiler enforces scope rules on `ref` fields in `ref struct` types. The rules ensure that a reference doesn't outlive the object to which it refers. See the section on scoping rules in the article on [method parameters](../keywords/method-parameters.md#scope-of-references-and-values).

Typically, you define a `ref struct` type when you need a type that also includes data members of `ref struct` types:

:::code language="csharp" source="snippets/shared/StructType.cs" id="SnippetRefStruct":::

To declare a `ref struct` as `readonly`, combine the `readonly` and `ref` modifiers in the type declaration (the `readonly` modifier must come before the `ref` modifier):

:::code language="csharp" source="snippets/shared/StructType.cs" id="SnippetReadonlyRef":::

In .NET, examples of a `ref struct` are <xref:System.Span%601?displayProperty=nameWithType> and <xref:System.ReadOnlySpan%601?displayProperty=nameWithType>.

## 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 about features introduced in C# 7.2 and later, see the following feature proposal notes:

- [Compile-time safety for ref-like types](~/_csharplang/proposals/csharp-7.2/span-safety.md)
Loading