From a55f2b5ab6d86b53fc18f70cf0c486b43cb91ac0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 2 Jul 2025 14:36:16 +0000 Subject: [PATCH 1/3] Initial plan From c553709ae15e827cd6a85ac3e50bdc1e4cd30c21 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 3 Jul 2025 14:00:12 +0000 Subject: [PATCH 2/3] Fix inconsistencies and improve clarity in type pattern matching conditions Co-authored-by: BillWagner <493969+BillWagner@users.noreply.github.com> --- docs/csharp/language-reference/operators/patterns.md | 10 ++++++---- .../operators/type-testing-and-cast.md | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/csharp/language-reference/operators/patterns.md b/docs/csharp/language-reference/operators/patterns.md index 976b3fde1f7ec..569348f1d5143 100644 --- a/docs/csharp/language-reference/operators/patterns.md +++ b/docs/csharp/language-reference/operators/patterns.md @@ -47,13 +47,15 @@ You use declaration and type patterns to check if the run-time type of an expres A *declaration pattern* with type `T` matches an expression when an expression result is non-null and any of the following conditions are true: -- The run-time type of an expression result is `T`. +- The run-time type of an expression result is exactly `T`. - The type `T` is a `ref struct` type and there is an identity conversion from the expression to `T`. -- The run-time type of an expression result derives from type `T`, implements interface `T`, or another [implicit reference conversion](~/_csharpstandard/standard/conversions.md#1028-implicit-reference-conversions) exists from it to `T`. The following example demonstrates two cases when this condition is true: +- The run-time type of an expression result derives from type `T`, implements interface `T`, or another [implicit reference conversion](~/_csharpstandard/standard/conversions.md#1028-implicit-reference-conversions) exists from it to `T`. This covers inheritance relationships and interface implementations. The following example demonstrates two cases when this condition is true: :::code language="csharp" source="snippets/patterns/DeclarationAndTypePatterns.cs" id="ReferenceConversion"::: In the preceding example, at the first call to the `GetSourceLabel` method, the first pattern matches an argument value because the argument's run-time type `int[]` derives from the type. At the second call to the `GetSourceLabel` method, the argument's run-time type doesn't derive from the type but implements the interface. -- The run-time type of an expression result is a [nullable value type](../builtin-types/nullable-value-types.md) with the underlying type `T`. -- A [boxing](../../programming-guide/types/boxing-and-unboxing.md#boxing) or [unboxing](../../programming-guide/types/boxing-and-unboxing.md#unboxing) conversion exists from the run-time type of an expression result to type `T`. +- The run-time type of an expression result is a [nullable value type](../builtin-types/nullable-value-types.md) with the underlying type `T` and the is `true`. +- A [boxing](../../programming-guide/types/boxing-and-unboxing.md#boxing) or [unboxing](../../programming-guide/types/boxing-and-unboxing.md#unboxing) conversion exists from the run-time type of an expression result to type `T` when the expression isn't an instance of a `ref struct`. + +Declaration patterns don't consider user-defined conversions or implicit span conversions. The following example demonstrates the last two conditions: diff --git a/docs/csharp/language-reference/operators/type-testing-and-cast.md b/docs/csharp/language-reference/operators/type-testing-and-cast.md index e482d330918a0..c0a13a412d347 100644 --- a/docs/csharp/language-reference/operators/type-testing-and-cast.md +++ b/docs/csharp/language-reference/operators/type-testing-and-cast.md @@ -39,9 +39,9 @@ Where `E` is an expression that returns a value and `T` is the name of a type or The `is` operator returns `true` when an expression result is non-null and any of the following conditions are true: -- The run-time type of an expression result is `T`. +- The run-time type of an expression result is exactly `T`. -- The run-time type of an expression result derives from type `T`, implements interface `T`, or another [implicit reference conversion](~/_csharpstandard/standard/conversions.md#1028-implicit-reference-conversions) exists from it to `T`. +- The run-time type of an expression result derives from type `T`, implements interface `T`, or another [implicit reference conversion](~/_csharpstandard/standard/conversions.md#1028-implicit-reference-conversions) exists from it to `T`. This covers inheritance relationships and interface implementations. - The run-time type of an expression result is a [nullable value type](../builtin-types/nullable-value-types.md) with the underlying type `T` and the is `true`. From 74b81856fc2e757c5d3d69dfdeaa2523c57eb1b1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 3 Jul 2025 15:05:08 +0000 Subject: [PATCH 3/3] Replace "exactly T" with "identity conversion to T" for tuple type compatibility Co-authored-by: BillWagner <493969+BillWagner@users.noreply.github.com> --- docs/csharp/language-reference/operators/patterns.md | 2 +- .../language-reference/operators/type-testing-and-cast.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/csharp/language-reference/operators/patterns.md b/docs/csharp/language-reference/operators/patterns.md index 569348f1d5143..2299ac2518eff 100644 --- a/docs/csharp/language-reference/operators/patterns.md +++ b/docs/csharp/language-reference/operators/patterns.md @@ -47,7 +47,7 @@ You use declaration and type patterns to check if the run-time type of an expres A *declaration pattern* with type `T` matches an expression when an expression result is non-null and any of the following conditions are true: -- The run-time type of an expression result is exactly `T`. +- The run-time type of an expression result has an identity conversion to `T`. - The type `T` is a `ref struct` type and there is an identity conversion from the expression to `T`. - The run-time type of an expression result derives from type `T`, implements interface `T`, or another [implicit reference conversion](~/_csharpstandard/standard/conversions.md#1028-implicit-reference-conversions) exists from it to `T`. This covers inheritance relationships and interface implementations. The following example demonstrates two cases when this condition is true: :::code language="csharp" source="snippets/patterns/DeclarationAndTypePatterns.cs" id="ReferenceConversion"::: diff --git a/docs/csharp/language-reference/operators/type-testing-and-cast.md b/docs/csharp/language-reference/operators/type-testing-and-cast.md index c0a13a412d347..4df9e94f4f547 100644 --- a/docs/csharp/language-reference/operators/type-testing-and-cast.md +++ b/docs/csharp/language-reference/operators/type-testing-and-cast.md @@ -39,7 +39,7 @@ Where `E` is an expression that returns a value and `T` is the name of a type or The `is` operator returns `true` when an expression result is non-null and any of the following conditions are true: -- The run-time type of an expression result is exactly `T`. +- The run-time type of an expression result has an identity conversion to `T`. - The run-time type of an expression result derives from type `T`, implements interface `T`, or another [implicit reference conversion](~/_csharpstandard/standard/conversions.md#1028-implicit-reference-conversions) exists from it to `T`. This covers inheritance relationships and interface implementations.