From 1a95936ce07eb30729b12e458484255656fbde0b Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Mon, 17 Aug 2026 14:29:53 -0400 Subject: [PATCH 1/7] Fist pass on tuple diagnostics --- .../compiler-messages/tuple-errors.md | 156 ++++++++++++++++++ docs/csharp/language-reference/toc.yml | 6 + ...n-t-have-specifics-on-this-csharp-error.md | 11 -- 3 files changed, 162 insertions(+), 11 deletions(-) create mode 100644 docs/csharp/language-reference/compiler-messages/tuple-errors.md diff --git a/docs/csharp/language-reference/compiler-messages/tuple-errors.md b/docs/csharp/language-reference/compiler-messages/tuple-errors.md new file mode 100644 index 0000000000000..956c0b4b6dc2c --- /dev/null +++ b/docs/csharp/language-reference/compiler-messages/tuple-errors.md @@ -0,0 +1,156 @@ +--- +title: "Resolve errors and warnings related to tuples" +description: "This article helps you diagnose and correct compiler errors and warnings related to tuple names, metadata, conversions, and equality" +f1_keywords: + - CS8123 + - CS8126 + - CS8128 + - CS8135 + - CS8137 + - CS8138 + - CS8179 + - CS8182 + - CS8307 + - CS8383 + - CS8384 +helpviewer_keywords: + - CS8123 + - CS8126 + - CS8128 + - CS8135 + - CS8137 + - CS8138 + - CS8179 + - CS8182 + - CS8307 + - CS8383 + - CS8384 +ms.date: 08/17/2026 +ai-usage: ai-assisted +--- + +# Resolve errors and warnings for tuples + +This article covers the following compiler errors and warnings: + + + +- [**CS8123**](#tuple-element-name-conflicts): *The tuple element name 'name' is ignored because a different name or no name is specified by the target type 'type'.* +- [**CS8126**](#tuple-element-names-reserved): *Tuple element name 'name' is disallowed at any position.* +- [**CS8128**](#valuetuple-types-missing): *Member 'member' was not found on type 'type' from assembly 'assembly'.* +- [**CS8135**](#tuple-cardinality-mismatch): *Tuple with 'count' elements cannot be converted to type 'type'.* +- [**CS8137**](#tuple-names-attribute-unavailable): *Cannot define a class or member that utilizes tuples because the compiler required type 'type' cannot be found. Are you missing a reference?* +- [**CS8138**](#tuple-names-attribute-unavailable): *Cannot reference 'System.Runtime.CompilerServices.TupleElementNamesAttribute' explicitly. Use the tuple syntax to define tuple names.* +- [**CS8179**](#valuetuple-types-missing): *Predefined type 'type' is not defined or imported* +- [**CS8182**](#valuetuple-types-missing): *Predefined type 'type' must be a struct.* +- [**CS8307**](#tuple-literal-type-inference): *The first operand of an 'as' operator may not be a tuple literal without a natural type.* +- [**CS8383**](#tuple-equality-element-name-conflicts): *The tuple element name 'name' is ignored because a different name or no name is specified on the other side of the tuple == or != operator.* +- [**CS8384**](#tuple-equality-cardinality-mismatch): *Tuple types used as operands of an == or != operator must have matching cardinalities. But this operator has tuple types of cardinality 'left' on the left and 'right' on the right.* + +## Tuple element names and conflicts + +### Tuple element name conflicts + +- **CS8123**: *The tuple element name 'name' is ignored because a different name or no name is specified by the target type 'type'.* +- **CS8383**: *The tuple element name 'name' is ignored because a different name or no name is specified on the other side of the tuple == or != operator.* + +The compiler warns when a tuple literal provides element names but the target type expects different names or no names. This can happen when assigning to a tuple type with unnamed elements or when comparing tuples with mismatched element names. + +To resolve these warnings: + +- If the element names in your tuple literal don't match the target type, either remove the names from the tuple literal or change the target type to use the same names (**CS8123**). +- When comparing tuples with the `==` or `!=` operator, ensure both operands have matching element names or both have no names. If you intentionally want to compare tuples with different naming conventions, ignore this warning (**CS8383**). + +### Tuple element names reserved + +- **CS8126**: *Tuple element name 'name' is disallowed at any position.* + +Certain element names like `Rest` and `ToString` are reserved for internal tuple structure and cannot be used as tuple element names. The C# compiler requires these names to be available on the tuple's underlying `ValueTuple` type. + +To resolve this error: + +- Choose a different name for the tuple element. Avoid reserved names like `Rest`, `ToString`, and other members of the `System.Runtime.CompilerServices.ITuple` interface (**CS8126**). + +## Tuple metadata and infrastructure + +### Tuple names attribute unavailable + +- **CS8137**: *Cannot define a class or member that utilizes tuples because the compiler required type 'type' cannot be found. Are you missing a reference?* +- **CS8138**: *Cannot reference 'System.Runtime.CompilerServices.TupleElementNamesAttribute' explicitly. Use the tuple syntax to define tuple names.* + +When a type signature includes named tuples, the compiler must be able to reference the `TupleElementNamesAttribute` to store the element names in metadata. Errors occur when this attribute is unavailable or when you explicitly reference it in source code. + +To resolve these errors: + +- For **CS8137**: Ensure you have a reference to the .NET runtime that provides `System.Runtime.CompilerServices.TupleElementNamesAttribute`. This attribute is included in the `System.Runtime` NuGet package on older frameworks. Add the reference and rebuild (**CS8137**). +- For **CS8138**: Use tuple literal syntax with element names (`(int x, string y)`) rather than explicitly writing `[TupleElementNames(...)]`. The compiler automatically generates the attribute metadata when it encounters named tuples in your code (**CS8138**). + +### ValueTuple types missing + +- **CS8179**: *Predefined type 'type' is not defined or imported* +- **CS8182**: *Predefined type 'type' must be a struct.* +- **CS8128**: *Member 'member' was not found on type 'type' from assembly 'assembly'.* + +These errors occur when the compiler cannot find the required `System.ValueTuple` or related tuple infrastructure types, or when a referenced tuple type doesn't match the expected structure. + +To resolve these errors: + +- For **CS8179**: Ensure your project references the .NET runtime that provides `System.ValueTuple`. This type is built into .NET Framework 4.7+, .NET Core, and .NET 5+. For older frameworks, add a reference to the `System.ValueTuple` NuGet package (**CS8179**). +- For **CS8182**: Verify that the `ValueTuple` type in your referenced assembly is defined as a `struct`. This is the expected implementation. If a custom `ValueTuple` type exists in your codebase, ensure it's a `struct` type (**CS8182**). +- For **CS8128**: The tuple infrastructure expects specific members (such as `Item1`, `Item2`, and `Rest` for large tuples) on the predefined `ValueTuple` types. This error indicates a mismatch between what the compiler expects and what was found in the referenced assembly. Verify that you're referencing the correct version of the runtime (**CS8128**). + +## Tuple conversions and literals + +### Tuple cardinality mismatch + +- **CS8135**: *Tuple with 'count' elements cannot be converted to type 'type'.* + +The compiler reports this error when you attempt to assign or convert a tuple with one number of elements to a type expecting a different number of elements. + +To resolve this error: + +- Ensure that the tuple literal has the same number of elements as the target tuple type. If converting from a tuple with 2 elements to a type expecting 3 elements, add or remove elements as needed (**CS8135**). + +### Tuple literal type inference + +- **CS8307**: *The first operand of an 'as' operator may not be a tuple literal without a natural type.* + +The `as` operator requires type information to work correctly. A bare tuple literal without explicit type annotation doesn't have a "natural type" that the compiler can infer, so you cannot use it directly as the left operand of `as`. + +To resolve this error: + +- Provide an explicit type annotation for the tuple literal. Cast it to the desired type first: `((int x, string y) as object)` or `((int, string) tuple as object)` (**CS8307**). +- Alternatively, assign the tuple to a variable first: `var t = (1, "hello"); var obj = t as object;` + +## Tuple equality + +### Tuple equality element name conflicts + +- **CS8383**: *The tuple element name 'name' is ignored because a different name or no name is specified on the other side of the tuple == or != operator.* + +When comparing two tuples with the `==` or `!=` operator, the compiler warns if the tuples have mismatched element names. Element names don't affect runtime equality, but the mismatch suggests a potential logical error. + +To resolve this warning: + +- Ensure both tuples in the comparison have the same element names or both have no names. For example, compare `(int x, string y)` with `(int x, string y)`, not with `(int a, string b)`. +- If the naming mismatch is intentional, you can suppress the warning or document the reason in your code. + +### Tuple equality cardinality mismatch + +- **CS8384**: *Tuple types used as operands of an == or != operator must have matching cardinalities. But this operator has tuple types of cardinality 'left' on the left and 'right' on the right.* + +You cannot use the `==` or `!=` operator to compare tuples with different numbers of elements. Tuples of different sizes are fundamentally incompatible types. + +To resolve this error: + +- Ensure both tuples have the same number of elements. Adjust your tuple literals or variable declarations to match the expected cardinality (**CS8384**). +- If you need to compare tuples of different sizes, consider comparing individual elements or converting one tuple's structure to match the other. + +## See also + +- [Value tuples](../builtin-types/value-tuples.md) +- [Deconstruction](../../fundamentals/functional/deconstruct.md) +- [Pattern matching](../../fundamentals/functional/pattern-matching.md) + diff --git a/docs/csharp/language-reference/toc.yml b/docs/csharp/language-reference/toc.yml index 6d25c0e978bc3..a15a79a940a41 100644 --- a/docs/csharp/language-reference/toc.yml +++ b/docs/csharp/language-reference/toc.yml @@ -518,6 +518,12 @@ items: displayName: > CS0017, CS0028, CS0402, CS1555, CS1556, CS1557, CS1558, CS1559, CS2017, CS5001, CS7022, CS8801, CS8802, CS8803, CS8805, CS8899, CS8937 + - name: Tuple declarations + href: ./compiler-messages/tuple-errors.md + displayName: > + tuples, tuple element names, tuple metadata, tuple conversions, tuple equality, + CS8123, CS8126, CS8128, CS8135, CS8137, CS8138, CS8179, CS8182, CS8307, CS8383, + CS8384 - name: Record declarations href: ./compiler-messages/record-declaration-errors.md displayName: > diff --git a/docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md b/docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md index b99526fdabc49..05951a75304c0 100644 --- a/docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md +++ b/docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md @@ -160,17 +160,9 @@ f1_keywords: - "CS8113" # C# 7.0 diagnostics - "CS8115" - - "CS8123" - - "CS8126" - - "CS8128" - "CS8134" - - "CS8135" - "CS8136" - - "CS8137" - - "CS8138" - - "CS8179" - "CS8180" - - "CS8182" - "CS8183" - "CS8184" - "CS8185" @@ -190,7 +182,6 @@ f1_keywords: - "CS8300" - "CS8301" - "CS8305" - - "CS8307" - "CS8308" - "CS8309" - "CS8310" @@ -214,8 +205,6 @@ f1_keywords: # C# 7.3 diagnostics - "CS8378" - "CS8381" - - "CS8383" - - "CS8384" # Coming in C# 15 - "CS9343" # misc - "CS9347" From 34d3ba057cb66c51640b90ac86886da0b846fbff Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Mon, 17 Aug 2026 15:30:12 -0400 Subject: [PATCH 2/7] Consolidate additional errors and warnings Consolidate the additional errors and warnings related to tuple declarations. --- .openpublishing.redirection.csharp.json | 28 ++ .../compiler-messages/cs8124.md | 36 --- .../compiler-messages/cs8125.md | 39 --- .../compiler-messages/cs8127.md | 42 --- .../compiler-messages/cs8139.md | 41 --- .../compiler-messages/cs8140.md | 60 ---- .../compiler-messages/cs8141.md | 45 --- .../compiler-messages/cs8210.md | 35 --- .../compiler-messages/tuple-errors.md | 266 ++++++++++++++---- docs/csharp/language-reference/toc.yml | 21 +- 10 files changed, 237 insertions(+), 376 deletions(-) delete mode 100644 docs/csharp/language-reference/compiler-messages/cs8124.md delete mode 100644 docs/csharp/language-reference/compiler-messages/cs8125.md delete mode 100644 docs/csharp/language-reference/compiler-messages/cs8127.md delete mode 100644 docs/csharp/language-reference/compiler-messages/cs8139.md delete mode 100644 docs/csharp/language-reference/compiler-messages/cs8140.md delete mode 100644 docs/csharp/language-reference/compiler-messages/cs8141.md delete mode 100644 docs/csharp/language-reference/compiler-messages/cs8210.md diff --git a/.openpublishing.redirection.csharp.json b/.openpublishing.redirection.csharp.json index b3feedae1279f..854d17b31097d 100644 --- a/.openpublishing.redirection.csharp.json +++ b/.openpublishing.redirection.csharp.json @@ -590,6 +590,30 @@ "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs7000.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors" }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs8124.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/tuple-errors" + }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs8125.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/tuple-errors" + }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs8127.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/tuple-errors" + }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs8139.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/tuple-errors" + }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs8140.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/tuple-errors" + }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs8141.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/tuple-errors" + }, { "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs8145.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" @@ -638,6 +662,10 @@ "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs8178.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/async-await-errors" }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs8210.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/tuple-errors" + }, { "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs8373.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/ref-modifiers-errors" diff --git a/docs/csharp/language-reference/compiler-messages/cs8124.md b/docs/csharp/language-reference/compiler-messages/cs8124.md deleted file mode 100644 index 3b745c8740486..0000000000000 --- a/docs/csharp/language-reference/compiler-messages/cs8124.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -description: "Compiler Error CS8124" -title: "Compiler Error CS8124" -ms.date: 9/30/2022 -f1_keywords: - - "CS8124" -helpviewer_keywords: - - "CS8124" ---- -# Compiler Error CS8124 - -Tuple must contain at least two elements. - -## Example - - The following sample generates CS8124: - -```csharp -// CS8124.cs (4,20) - -class C -{ - void M(int x, () y, (int a) z) { } -} -``` - -## To correct this error - -A valid tuple declaration contains two or more elements, ensuring tuple declarations have two or more elements corrects this error: - -```csharp -class C -{ - void M(int x, (int, int) y, (int a, int b) z) { } -} -``` diff --git a/docs/csharp/language-reference/compiler-messages/cs8125.md b/docs/csharp/language-reference/compiler-messages/cs8125.md deleted file mode 100644 index 6d7a2a7cb44c6..0000000000000 --- a/docs/csharp/language-reference/compiler-messages/cs8125.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -description: "Compiler Error CS8125" -title: "Compiler Error CS8125" -ms.date: 9/30/2022 -f1_keywords: - - "CS8125" -helpviewer_keywords: - - "CS8125" ---- -# Compiler Error CS8125 - -Tuple element name is only allowed at position. - -## Example - - The following sample generates CS8125: - -```csharp -// CS8125.cs (2,15) - -public class C -{ - public void Method() - { - var tuple3 = (Item2: 2, Item1: 1); - } -} -``` - -## To correct this error - -If tuple element names `Item1`, `Item2`, etc. are used, ensuring the correct order corrects this error: - -```csharp - public void Method() - { - var tuple3 = (Item1: 2, Item2: 1); - } -``` diff --git a/docs/csharp/language-reference/compiler-messages/cs8127.md b/docs/csharp/language-reference/compiler-messages/cs8127.md deleted file mode 100644 index 036fa67654075..0000000000000 --- a/docs/csharp/language-reference/compiler-messages/cs8127.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -description: "Compiler Error CS8127" -title: "Compiler Error CS8127" -ms.date: 9/30/2022 -f1_keywords: - - "CS8127" -helpviewer_keywords: - - "CS8127" ---- -# Compiler Error CS8127 - -Tuple element names must be unique. - -## Example - - The following sample generates CS8127: - -```csharp -// CS8127.cs (7,0) - -internal struct NewStruct -{ - public int a; - public int b; - - public static implicit operator (int a, int a)(NewStruct value) - { - return (value.a, value.b); - } -} -``` - -## To correct this error - -Ensuring the names of elements within a tuple declaration are unique corrects this error: - -```csharp - public static implicit operator (int a, int b)(NewStruct value) - { - return (value.a, value.b); - } -``` diff --git a/docs/csharp/language-reference/compiler-messages/cs8139.md b/docs/csharp/language-reference/compiler-messages/cs8139.md deleted file mode 100644 index d7c863eee3804..0000000000000 --- a/docs/csharp/language-reference/compiler-messages/cs8139.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -description: "Compiler Error CS8139" -title: "Compiler Error CS8139" -ms.date: 9/30/2022 -f1_keywords: - - "CS8139" -helpviewer_keywords: - - "CS8139" ---- -# Compiler Error CS8139 - -cannot change tuple element names when overriding inherited member - -## Example - - The following sample generates CS8139: - -```csharp -// CS8139.cs (9,38) - -public class Base -{ - public virtual (object a, object b) M((object c, object d) x) { return x; } -} - -class C : Base -{ - public override (object, object) M((object c, object d) y) { return y; } -} -``` - -## To correct this error - -Ensuring the tuple element names in the overriding member match those in the virtual member corrects this error: - -```csharp -class C : Base -{ - public override (object a, object b) M((object c, object d) y) { return y; } -} -``` diff --git a/docs/csharp/language-reference/compiler-messages/cs8140.md b/docs/csharp/language-reference/compiler-messages/cs8140.md deleted file mode 100644 index 4628539900de7..0000000000000 --- a/docs/csharp/language-reference/compiler-messages/cs8140.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -description: "Compiler Error CS8140" -title: "Compiler Error CS8140" -ms.date: 9/30/2022 -f1_keywords: - - "CS8140" -helpviewer_keywords: - - "CS8140" ---- -# Compiler Error CS8140 - -is already listed in the interface list on type with different tuple element names, as. - -## Example - - The following sample generates CS8140: - -```csharp -// CS8140.cs (11,7) - -interface I -{ - T GetValue(); -} - -interface I2 : I<(int c, int d)> -{ -} - -class C : I<(int a, int b)>, I2 -{ - public (int c, int d) GetValue() - { - return (1, 2); - } -} -``` - -## To correct this error - -Renaming the tuple element names to match the interface declaration corrects this error: - -```csharp -interface I -{ - T GetValue(); -} - -interface I2 : I<(int c, int d)> -{ -} - -class C : I<(int c, int d)>, I2 -{ - public (int c, int d) GetValue() - { - return (1, 2); - } -} -``` diff --git a/docs/csharp/language-reference/compiler-messages/cs8141.md b/docs/csharp/language-reference/compiler-messages/cs8141.md deleted file mode 100644 index 8e99744d298ac..0000000000000 --- a/docs/csharp/language-reference/compiler-messages/cs8141.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -description: "Compiler Error CS8141" -title: "Compiler Error CS8141" -ms.date: 9/30/2022 -f1_keywords: - - "CS8141" -helpviewer_keywords: - - "CS8141" ---- -# Compiler Error CS8141 - -The tuple element names in the signature of method must match the tuple element names of interface method (including on the return type). - -## Example - -The following sample generates CS8141: - -```csharp -// CS8141.cs (10,27) -using System.Collections; - -public interface IGrabber -{ - T GetOne(); -} - -class SomeGrabber : IGrabber<(int, int)> -{ - public (int a, int b) GetOne() - { - return (1, 2); - } -} -``` - -## To correct this error - -Changing the signature of the `GetOne` method to return an unnamed tuple, matching the unnamed tuple in the interface, will correct this error: - -```csharp - public (int, int) GetOne() - { - return (1, 2); - } -``` diff --git a/docs/csharp/language-reference/compiler-messages/cs8210.md b/docs/csharp/language-reference/compiler-messages/cs8210.md deleted file mode 100644 index 1969a7e5e8e53..0000000000000 --- a/docs/csharp/language-reference/compiler-messages/cs8210.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -description: "Compiler Error CS8210" -title: "Compiler Error CS8210" -ms.date: 10/26/2022 -f1_keywords: - - "CS8210" -helpviewer_keywords: - - "CS8210" ---- -# Compiler Error CS8210 - -A tuple may not contain a value of type 'void'. - -## Example - - The following sample generates CS8210: - -```csharp -// CS8210.cs -void Method() -{ -} - -void Test() -{ - var x = ("something", Method()); -} -``` - -Your method returns `void`, so that method doesn't return a value. You can't use a method that returns `void` for a data member of a tuple. - -## See also - -- [Tuple](../builtin-types/value-tuples.md) -- [Void](../builtin-types/void.md) diff --git a/docs/csharp/language-reference/compiler-messages/tuple-errors.md b/docs/csharp/language-reference/compiler-messages/tuple-errors.md index 956c0b4b6dc2c..fab45593dd843 100644 --- a/docs/csharp/language-reference/compiler-messages/tuple-errors.md +++ b/docs/csharp/language-reference/compiler-messages/tuple-errors.md @@ -1,30 +1,54 @@ --- title: "Resolve errors and warnings related to tuples" -description: "This article helps you diagnose and correct compiler errors and warnings related to tuple names, metadata, conversions, and equality" +description: "This article helps you diagnose and correct compiler errors and warnings related to tuple declarations, element names, metadata, conversions, equality, type inference, and pattern matching" f1_keywords: - CS8123 + - CS8124 + - CS8125 - CS8126 + - CS8127 - CS8128 - CS8135 - CS8137 - CS8138 + - CS8139 + - CS8140 + - CS8141 + - CS8142 - CS8179 + - CS8181 - CS8182 + - CS8210 + - CS8306 - CS8307 - CS8383 - CS8384 + - CS8516 + - CS8522 helpviewer_keywords: - CS8123 + - CS8124 + - CS8125 - CS8126 + - CS8127 - CS8128 - CS8135 - CS8137 - CS8138 + - CS8139 + - CS8140 + - CS8141 + - CS8142 - CS8179 + - CS8181 - CS8182 + - CS8210 + - CS8306 - CS8307 - CS8383 - CS8384 + - CS8516 + - CS8522 ms.date: 08/17/2026 ai-usage: ai-assisted --- @@ -37,120 +61,240 @@ This article covers the following compiler errors and warnings: That's by design. The text closely matches the text of the compiler error / warning for SEO purposes. --> -- [**CS8123**](#tuple-element-name-conflicts): *The tuple element name 'name' is ignored because a different name or no name is specified by the target type 'type'.* -- [**CS8126**](#tuple-element-names-reserved): *Tuple element name 'name' is disallowed at any position.* -- [**CS8128**](#valuetuple-types-missing): *Member 'member' was not found on type 'type' from assembly 'assembly'.* -- [**CS8135**](#tuple-cardinality-mismatch): *Tuple with 'count' elements cannot be converted to type 'type'.* -- [**CS8137**](#tuple-names-attribute-unavailable): *Cannot define a class or member that utilizes tuples because the compiler required type 'type' cannot be found. Are you missing a reference?* -- [**CS8138**](#tuple-names-attribute-unavailable): *Cannot reference 'System.Runtime.CompilerServices.TupleElementNamesAttribute' explicitly. Use the tuple syntax to define tuple names.* -- [**CS8179**](#valuetuple-types-missing): *Predefined type 'type' is not defined or imported* -- [**CS8182**](#valuetuple-types-missing): *Predefined type 'type' must be a struct.* -- [**CS8307**](#tuple-literal-type-inference): *The first operand of an 'as' operator may not be a tuple literal without a natural type.* -- [**CS8383**](#tuple-equality-element-name-conflicts): *The tuple element name 'name' is ignored because a different name or no name is specified on the other side of the tuple == or != operator.* -- [**CS8384**](#tuple-equality-cardinality-mismatch): *Tuple types used as operands of an == or != operator must have matching cardinalities. But this operator has tuple types of cardinality 'left' on the left and 'right' on the right.* +- [**CS8123**](#tuple-element-names): *The tuple element name 'name' is ignored because a different name or no name is specified by the target type 'type'.* +- [**CS8124**](#tuple-structure-and-literals): *Tuple must contain at least two elements.* +- [**CS8125**](#tuple-element-names): *Tuple element name 'name' is only allowed at position N.* +- [**CS8126**](#tuple-element-names): *Tuple element name 'name' is disallowed at any position.* +- [**CS8127**](#tuple-element-names): *Tuple element names must be unique.* +- [**CS8128**](#valuetuple-infrastructure): *Member 'member' was not found on type 'type' from assembly 'assembly'.* +- [**CS8135**](#tuple-structure-and-literals): *Tuple with 'count' elements cannot be converted to type 'type'.* +- [**CS8137**](#tuple-metadata): *Cannot define a class or member that utilizes tuples because the compiler required type 'type' cannot be found. Are you missing a reference?* +- [**CS8138**](#tuple-metadata): *Cannot reference 'System.Runtime.CompilerServices.TupleElementNamesAttribute' explicitly. Use the tuple syntax to define tuple names.* +- [**CS8139**](#tuple-element-names-in-type-hierarchy): *'member': cannot change tuple element names when overriding inherited member 'base member'.* +- [**CS8140**](#tuple-element-names-in-type-hierarchy): *'interface' is already listed in the interface list on type 'type' with different tuple element names, as 'alias'.* +- [**CS8141**](#tuple-element-names-in-type-hierarchy): *The tuple element names in the signature of method 'method' must match the tuple element names of interface method 'interface method' (including on the return type).* +- [**CS8142**](#tuple-element-names-in-type-hierarchy): *Both partial member declarations, 'member' and 'other partial', must use the same tuple element names.* +- [**CS8179**](#valuetuple-infrastructure): *Predefined type 'type' is not defined or imported* +- [**CS8181**](#tuple-structure-and-literals): *'new' cannot be used with tuple type. Use a tuple literal expression instead.* +- [**CS8182**](#valuetuple-infrastructure): *Predefined type 'type' must be a struct.* +- [**CS8210**](#tuple-structure-and-literals): *A tuple may not contain a value of type 'void'.* +- [**CS8306**](#tuple-type-inference): *Tuple element name 'name' is inferred. Please use language version 7.1 or greater to access an element by its inferred name.* +- [**CS8307**](#tuple-type-inference): *The first operand of an 'as' operator may not be a tuple literal without a natural type.* +- [**CS8383**](#tuple-equality): *The tuple element name 'name' is ignored because a different name or no name is specified on the other side of the tuple == or != operator.* +- [**CS8384**](#tuple-equality): *Tuple types used as operands of an == or != operator must have matching cardinalities. But this operator has tuple types of cardinality 'left' on the left and 'right' on the right.* +- [**CS8516**](#pattern-matching-with-tuples): *The name 'name' does not identify tuple element 'element'.* +- [**CS8522**](#pattern-matching-with-tuples): *Element names are not permitted when pattern-matching via 'System.Runtime.CompilerServices.ITuple'.* + +## Tuple element names -## Tuple element names and conflicts +- **CS8123**: *The tuple element name 'name' is ignored because a different name or no name is specified by the target type 'type'.* +- **CS8125**: *Tuple element name 'name' is only allowed at position N.* +- **CS8126**: *Tuple element name 'name' is disallowed at any position.* +- **CS8127**: *Tuple element names must be unique.* -### Tuple element name conflicts +The compiler warns or reports an error when tuple element names are inconsistent with the surrounding context. -- **CS8123**: *The tuple element name 'name' is ignored because a different name or no name is specified by the target type 'type'.* -- **CS8383**: *The tuple element name 'name' is ignored because a different name or no name is specified on the other side of the tuple == or != operator.* +**CS8123** is a warning that appears when a tuple literal provides element names, but the target type expects different names or no names. Element names in a tuple literal are ignored during type conversion; assigning a named tuple to a variable of an unnamed or differently named tuple type does not copy the names. Rename the element names in the tuple literal to match the target type, or change the target type to preserve the intended names (**CS8123**). -The compiler warns when a tuple literal provides element names but the target type expects different names or no names. This can happen when assigning to a tuple type with unnamed elements or when comparing tuples with mismatched element names. +**CS8125** occurs when the reserved `ItemN` naming scheme is used but the name is placed at the wrong position. The names `Item1`, `Item2`, and so on are allowed only at their corresponding positions—`Item1` at position 1, `Item2` at position 2. For example, `(Item2: 2, Item1: 1)` is invalid because `Item2` is at position 1 and `Item1` is at position 2. Reorder the elements so that `ItemN` names correspond to their declared position, or use distinct custom names (**CS8125**). -To resolve these warnings: +**CS8126** occurs when a tuple element uses a name that is reserved for the tuple's underlying `ValueTuple` infrastructure. Names such as `Rest`, `ToString`, `GetHashCode`, `Equals`, and members of `System.Runtime.CompilerServices.ITuple` cannot be used as element names. Choose a different element name (**CS8126**). -- If the element names in your tuple literal don't match the target type, either remove the names from the tuple literal or change the target type to use the same names (**CS8123**). -- When comparing tuples with the `==` or `!=` operator, ensure both operands have matching element names or both have no names. If you intentionally want to compare tuples with different naming conventions, ignore this warning (**CS8383**). +**CS8127** occurs when two elements in the same tuple declaration use the same name. All element names within a tuple must be distinct. Rename one of the conflicting elements (**CS8127**): -### Tuple element names reserved +```csharp +internal struct NewStruct +{ + public int a; + public int b; -- **CS8126**: *Tuple element name 'name' is disallowed at any position.* + // Error: both elements named 'a' + // public static implicit operator (int a, int a)(NewStruct value) => (value.a, value.b); + + // Fix: use distinct names + public static implicit operator (int a, int b)(NewStruct value) => (value.a, value.b); +} +``` + +## Tuple element names in type hierarchy + +- **CS8139**: *'member': cannot change tuple element names when overriding inherited member 'base member'.* +- **CS8140**: *'interface' is already listed in the interface list on type 'type' with different tuple element names, as 'alias'.* +- **CS8141**: *The tuple element names in the signature of method 'method' must match the tuple element names of interface method 'interface method' (including on the return type).* +- **CS8142**: *Both partial member declarations, 'member' and 'other partial', must use the same tuple element names.* + +Tuple element names are part of the method signature and must be consistent across overrides, interface implementations, and partial member declarations. + +**CS8139** occurs when an overriding method changes the tuple element names from those declared in the virtual or abstract base member. Match the tuple element names in the overriding method's signature to those in the base member (**CS8139**): + +```csharp +public class Base +{ + public virtual (object a, object b) M((object c, object d) x) { return x; } +} + +class Derived : Base +{ + // Error: return type changed 'a','b' to unnamed + // public override (object, object) M((object c, object d) y) { return y; } + + // Fix: preserve names from base + public override (object a, object b) M((object c, object d) y) { return y; } +} +``` + +**CS8140** occurs when a class implements the same generic interface twice through inheritance, but with different tuple element names. The class cannot satisfy both simultaneously. Align the tuple element names across all base types and interface implementations so that all paths to the same generic interface use the same element names (**CS8140**): + +```csharp +interface I +{ + T GetValue(); +} + +interface I2 : I<(int c, int d)> +{ +} -Certain element names like `Rest` and `ToString` are reserved for internal tuple structure and cannot be used as tuple element names. The C# compiler requires these names to be available on the tuple's underlying `ValueTuple` type. +// Error: I is implemented via I2 with (int c, int d), +// but also directly with (int a, int b) +// class C : I<(int a, int b)>, I2 +// { +// public (int c, int d) GetValue() => (1, 2); +// } -To resolve this error: +// Fix: align element names across all paths to I +class C : I<(int c, int d)>, I2 +{ + public (int c, int d) GetValue() => (1, 2); +} +``` -- Choose a different name for the tuple element. Avoid reserved names like `Rest`, `ToString`, and other members of the `System.Runtime.CompilerServices.ITuple` interface (**CS8126**). +**CS8141** occurs when an explicit or implicit interface implementation uses different tuple element names than the interface member it implements. Match the tuple element names in the implementing method to those declared in the interface, for both parameters and return types (**CS8141**): -## Tuple metadata and infrastructure +```csharp +public interface IGrabber +{ + T GetOne(); +} -### Tuple names attribute unavailable +// Error: implementation adds names to unnamed tuple +// class SomeGrabber : IGrabber<(int, int)> +// { +// public (int a, int b) GetOne() => (1, 2); +// } + +// Fix: match the interface's unnamed tuple +class SomeGrabber : IGrabber<(int, int)> +{ + public (int, int) GetOne() => (1, 2); +} +``` + +**CS8142** occurs when the two halves of a partial method or property declaration specify different tuple element names. Both declarations must use exactly the same tuple element names. Update one declaration to match the other (**CS8142**). + +## Tuple metadata - **CS8137**: *Cannot define a class or member that utilizes tuples because the compiler required type 'type' cannot be found. Are you missing a reference?* - **CS8138**: *Cannot reference 'System.Runtime.CompilerServices.TupleElementNamesAttribute' explicitly. Use the tuple syntax to define tuple names.* -When a type signature includes named tuples, the compiler must be able to reference the `TupleElementNamesAttribute` to store the element names in metadata. Errors occur when this attribute is unavailable or when you explicitly reference it in source code. +When a type signature includes named tuples, the compiler must be able to reference `TupleElementNamesAttribute` to store the element names in metadata. -To resolve these errors: +**CS8137** occurs when `TupleElementNamesAttribute` itself is missing from the referenced runtime. Ensure your project references a .NET runtime that provides `System.Runtime.CompilerServices.TupleElementNamesAttribute`. For older frameworks, add a reference to the `System.Runtime` NuGet package and rebuild (**CS8137**). -- For **CS8137**: Ensure you have a reference to the .NET runtime that provides `System.Runtime.CompilerServices.TupleElementNamesAttribute`. This attribute is included in the `System.Runtime` NuGet package on older frameworks. Add the reference and rebuild (**CS8137**). -- For **CS8138**: Use tuple literal syntax with element names (`(int x, string y)`) rather than explicitly writing `[TupleElementNames(...)]`. The compiler automatically generates the attribute metadata when it encounters named tuples in your code (**CS8138**). +**CS8138** occurs when source code explicitly references `[TupleElementNames(...)]`. This attribute is reserved for compiler use and cannot be applied in source. Use tuple literal syntax with element names—for example, `(int x, string y)`—and the compiler will generate the metadata automatically (**CS8138**). -### ValueTuple types missing +## ValueTuple infrastructure +- **CS8128**: *Member 'member' was not found on type 'type' from assembly 'assembly'.* - **CS8179**: *Predefined type 'type' is not defined or imported* - **CS8182**: *Predefined type 'type' must be a struct.* -- **CS8128**: *Member 'member' was not found on type 'type' from assembly 'assembly'.* -These errors occur when the compiler cannot find the required `System.ValueTuple` or related tuple infrastructure types, or when a referenced tuple type doesn't match the expected structure. +These errors occur when the compiler cannot find or validate the required `System.ValueTuple` types that underlie tuple syntax. -To resolve these errors: +**CS8179** occurs when the `System.ValueTuple` type is completely absent. Tuples require this type. It is built into .NET Framework 4.7 and later, .NET Core, and .NET 5+. For older frameworks, add the `System.ValueTuple` NuGet package (**CS8179**). -- For **CS8179**: Ensure your project references the .NET runtime that provides `System.ValueTuple`. This type is built into .NET Framework 4.7+, .NET Core, and .NET 5+. For older frameworks, add a reference to the `System.ValueTuple` NuGet package (**CS8179**). -- For **CS8182**: Verify that the `ValueTuple` type in your referenced assembly is defined as a `struct`. This is the expected implementation. If a custom `ValueTuple` type exists in your codebase, ensure it's a `struct` type (**CS8182**). -- For **CS8128**: The tuple infrastructure expects specific members (such as `Item1`, `Item2`, and `Rest` for large tuples) on the predefined `ValueTuple` types. This error indicates a mismatch between what the compiler expects and what was found in the referenced assembly. Verify that you're referencing the correct version of the runtime (**CS8128**). +**CS8182** occurs when a `ValueTuple` type exists in the referenced assembly but is a class rather than a struct. The compiler requires it to be a struct. Verify that you are not shadowing the system `ValueTuple` types with a custom class in your project or a referenced assembly (**CS8182**). -## Tuple conversions and literals +**CS8128** occurs when a specific member (such as `Item1`, `Item2`, or `Rest` for large tuples) is missing from the predefined `ValueTuple` type in the referenced assembly. This usually indicates an assembly mismatch or a corrupted custom `ValueTuple` implementation. Verify that your project references the correct version of the runtime or NuGet package (**CS8128**). -### Tuple cardinality mismatch +## Tuple structure and literals +- **CS8124**: *Tuple must contain at least two elements.* - **CS8135**: *Tuple with 'count' elements cannot be converted to type 'type'.* +- **CS8181**: *'new' cannot be used with tuple type. Use a tuple literal expression instead.* +- **CS8210**: *A tuple may not contain a value of type 'void'.* -The compiler reports this error when you attempt to assign or convert a tuple with one number of elements to a type expecting a different number of elements. +These errors relate to how tuple expressions are formed. -To resolve this error: +**CS8124** occurs when a tuple type or literal declares fewer than two elements. Tuples require at least two elements. Change a zero- or one-element tuple to use two or more elements (**CS8124**): -- Ensure that the tuple literal has the same number of elements as the target tuple type. If converting from a tuple with 2 elements to a type expecting 3 elements, add or remove elements as needed (**CS8135**). +```csharp +// Error: () and (int a) are invalid tuple types +// void M(int x, () y, (int a) z) { } -### Tuple literal type inference +// Fix: use at least two elements +void M(int x, (int, int) y, (int a, int b) z) { } +``` -- **CS8307**: *The first operand of an 'as' operator may not be a tuple literal without a natural type.* +**CS8135** occurs when a tuple expression has a different number of elements than the target type expects. Ensure the tuple literal has the same element count as the destination type (**CS8135**). -The `as` operator requires type information to work correctly. A bare tuple literal without explicit type annotation doesn't have a "natural type" that the compiler can infer, so you cannot use it directly as the left operand of `as`. +**CS8181** occurs when you write `new (T1, T2)(...)` using `new` with a tuple type. Tuple values are created with tuple literal syntax, not with `new`. Replace `new (T1, T2)(v1, v2)` with the literal `(v1, v2)` (**CS8181**). -To resolve this error: +**CS8210** occurs when a tuple element expression evaluates to `void`—for example, by calling a `void`-returning method as a tuple element. Tuples can only contain values; they cannot hold a `void` result. Replace the `void` method call with an expression that produces a value, or redesign the tuple to exclude that element (**CS8210**): -- Provide an explicit type annotation for the tuple literal. Cast it to the desired type first: `((int x, string y) as object)` or `((int, string) tuple as object)` (**CS8307**). -- Alternatively, assign the tuple to a variable first: `var t = (1, "hello"); var obj = t as object;` +```csharp +void Method() +{ +} -## Tuple equality +void Test() +{ + // Error: Method() returns void and cannot be a tuple element + // var x = ("something", Method()); +} +``` + +## Tuple type inference -### Tuple equality element name conflicts +- **CS8306**: *Tuple element name 'name' is inferred. Please use language version 7.1 or greater to access an element by its inferred name.* +- **CS8307**: *The first operand of an 'as' operator may not be a tuple literal without a natural type.* + +**CS8306** occurs when code accesses an inferred tuple element name—a name derived from a variable or member expression, such as `(x, y).x`—but the project targets a language version earlier than C# 7.1. To resolve, set `7.1` or higher in your project file, or access the element by position (`Item1`, `Item2`) instead of its inferred name (**CS8306**). + +**CS8307** occurs when a tuple literal without explicit element types is used as the left operand of an `as` operator. The `as` operator requires type information, and a bare tuple literal has no natural type. Either assign the literal to a typed variable first, then apply `as` to the variable, or annotate the tuple with an explicit type before using `as` (**CS8307**). + +## Tuple equality - **CS8383**: *The tuple element name 'name' is ignored because a different name or no name is specified on the other side of the tuple == or != operator.* +- **CS8384**: *Tuple types used as operands of an == or != operator must have matching cardinalities. But this operator has tuple types of cardinality 'left' on the left and 'right' on the right.* -When comparing two tuples with the `==` or `!=` operator, the compiler warns if the tuples have mismatched element names. Element names don't affect runtime equality, but the mismatch suggests a potential logical error. +**CS8383** is a warning that appears when the two operands of a `==` or `!=` comparison have different or absent element names. Element names do not affect equality semantics—the comparison still compares element values positionally—but the mismatch often indicates a naming inconsistency. Align the element names on both sides of the operator, or use unnamed tuples if the names are not meaningful for this comparison (**CS8383**). -To resolve this warning: +**CS8384** occurs when the two operands of a `==` or `!=` comparison have different numbers of elements. Tuples of different sizes are not comparable. Adjust the tuple literals or types so that both operands have the same element count (**CS8384**). -- Ensure both tuples in the comparison have the same element names or both have no names. For example, compare `(int x, string y)` with `(int x, string y)`, not with `(int a, string b)`. -- If the naming mismatch is intentional, you can suppress the warning or document the reason in your code. +## Pattern matching with tuples -### Tuple equality cardinality mismatch +- **CS8516**: *The name 'name' does not identify tuple element 'element'.* +- **CS8522**: *Element names are not permitted when pattern-matching via 'System.Runtime.CompilerServices.ITuple'.* -- **CS8384**: *Tuple types used as operands of an == or != operator must have matching cardinalities. But this operator has tuple types of cardinality 'left' on the left and 'right' on the right.* +**CS8516** occurs when a tuple pattern uses a property name that does not match any element name of the tuple type being matched. Tuple patterns match elements by name; check the element names of the tuple type and correct the pattern property name (**CS8516**): + +```csharp +var point = (x: 1, y: 2); -You cannot use the `==` or `!=` operator to compare tuples with different numbers of elements. Tuples of different sizes are fundamentally incompatible types. +// Error: 'a' and 'b' do not identify elements of (int x, int y) +// if (point is (a: 1, b: _)) { } -To resolve this error: +// Fix: use the declared element names +if (point is (x: 1, y: _)) { } +``` -- Ensure both tuples have the same number of elements. Adjust your tuple literals or variable declarations to match the expected cardinality (**CS8384**). -- If you need to compare tuples of different sizes, consider comparing individual elements or converting one tuple's structure to match the other. +**CS8522** occurs when a positional pattern uses named subpatterns against a type that implements `System.Runtime.CompilerServices.ITuple` but is not a known tuple type. When pattern-matching via the `ITuple` interface, elements must be matched positionally, not by name. Remove the element names from the pattern (**CS8522**). ## See also - [Value tuples](../builtin-types/value-tuples.md) - [Deconstruction](../../fundamentals/functional/deconstruct.md) - [Pattern matching](../../fundamentals/functional/pattern-matching.md) +- [Void](../builtin-types/void.md) diff --git a/docs/csharp/language-reference/toc.yml b/docs/csharp/language-reference/toc.yml index a15a79a940a41..4aee87becdf0b 100644 --- a/docs/csharp/language-reference/toc.yml +++ b/docs/csharp/language-reference/toc.yml @@ -521,9 +521,10 @@ items: - name: Tuple declarations href: ./compiler-messages/tuple-errors.md displayName: > - tuples, tuple element names, tuple metadata, tuple conversions, tuple equality, - CS8123, CS8126, CS8128, CS8135, CS8137, CS8138, CS8179, CS8182, CS8307, CS8383, - CS8384 + tuples, tuple element names, tuple metadata, tuple conversions, tuple equality, tuple pattern matching, + CS8123, CS8124, CS8125, CS8126, CS8127, CS8128, CS8135, CS8137, CS8138, CS8139, + CS8140, CS8141, CS8142, CS8179, CS8181, CS8182, CS8210, CS8306, CS8307, CS8383, + CS8384, CS8516, CS8522 - name: Record declarations href: ./compiler-messages/record-declaration-errors.md displayName: > @@ -1561,12 +1562,6 @@ items: href: ./compiler-messages/cs7003.md - name: CS8070 href: ./compiler-messages/cs8070.md - - name: CS8124 - href: ./compiler-messages/cs8124.md - - name: CS8125 - href: ./compiler-messages/cs8125.md - - name: CS8127 - href: ./compiler-messages/cs8127.md - name: CS8129 href: ./compiler-messages/cs8129.md - name: CS8130 @@ -1575,12 +1570,6 @@ items: href: ./compiler-messages/cs8131.md - name: CS8132 href: ./compiler-messages/cs8132.md - - name: CS8139 - href: ./compiler-messages/cs8139.md - - name: CS8140 - href: ./compiler-messages/cs8140.md - - name: CS8141 - href: ./compiler-messages/cs8141.md - name: CS8146 href: ./compiler-messages/cs8146.md - name: CS8147 @@ -1621,8 +1610,6 @@ items: href: ./compiler-messages/cs8173.md - name: CS8174 href: ./compiler-messages/cs8174.md - - name: CS8210 - href: ./compiler-messages/cs8210.md - name: CS8333 href: ./compiler-messages/cs8333.md - name: CS8334 From cb8e6560632e118440fe8b83a942c959facf5cb6 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Mon, 17 Aug 2026 16:22:08 -0400 Subject: [PATCH 3/7] Final proofread. Wordsmithing and style guide practices. --- .../compiler-messages/tuple-errors.md | 173 ++---------------- docs/csharp/language-reference/toc.yml | 4 +- 2 files changed, 13 insertions(+), 164 deletions(-) diff --git a/docs/csharp/language-reference/compiler-messages/tuple-errors.md b/docs/csharp/language-reference/compiler-messages/tuple-errors.md index fab45593dd843..d3ee426352b23 100644 --- a/docs/csharp/language-reference/compiler-messages/tuple-errors.md +++ b/docs/csharp/language-reference/compiler-messages/tuple-errors.md @@ -16,10 +16,8 @@ f1_keywords: - CS8141 - CS8142 - CS8179 - - CS8181 - CS8182 - CS8210 - - CS8306 - CS8307 - CS8383 - CS8384 @@ -40,10 +38,8 @@ helpviewer_keywords: - CS8141 - CS8142 - CS8179 - - CS8181 - CS8182 - CS8210 - - CS8306 - CS8307 - CS8383 - CS8384 @@ -57,8 +53,8 @@ ai-usage: ai-assisted This article covers the following compiler errors and warnings: - - [**CS8123**](#tuple-element-names): *The tuple element name 'name' is ignored because a different name or no name is specified by the target type 'type'.* @@ -74,11 +70,9 @@ That's by design. The text closely matches the text of the compiler error / warn - [**CS8140**](#tuple-element-names-in-type-hierarchy): *'interface' is already listed in the interface list on type 'type' with different tuple element names, as 'alias'.* - [**CS8141**](#tuple-element-names-in-type-hierarchy): *The tuple element names in the signature of method 'method' must match the tuple element names of interface method 'interface method' (including on the return type).* - [**CS8142**](#tuple-element-names-in-type-hierarchy): *Both partial member declarations, 'member' and 'other partial', must use the same tuple element names.* -- [**CS8179**](#valuetuple-infrastructure): *Predefined type 'type' is not defined or imported* -- [**CS8181**](#tuple-structure-and-literals): *'new' cannot be used with tuple type. Use a tuple literal expression instead.* +- [**CS8179**](#valuetuple-infrastructure): *Predefined type 'type' is not defined or imported.* - [**CS8182**](#valuetuple-infrastructure): *Predefined type 'type' must be a struct.* - [**CS8210**](#tuple-structure-and-literals): *A tuple may not contain a value of type 'void'.* -- [**CS8306**](#tuple-type-inference): *Tuple element name 'name' is inferred. Please use language version 7.1 or greater to access an element by its inferred name.* - [**CS8307**](#tuple-type-inference): *The first operand of an 'as' operator may not be a tuple literal without a natural type.* - [**CS8383**](#tuple-equality): *The tuple element name 'name' is ignored because a different name or no name is specified on the other side of the tuple == or != operator.* - [**CS8384**](#tuple-equality): *Tuple types used as operands of an == or != operator must have matching cardinalities. But this operator has tuple types of cardinality 'left' on the left and 'right' on the right.* @@ -92,29 +86,7 @@ That's by design. The text closely matches the text of the compiler error / warn - **CS8126**: *Tuple element name 'name' is disallowed at any position.* - **CS8127**: *Tuple element names must be unique.* -The compiler warns or reports an error when tuple element names are inconsistent with the surrounding context. - -**CS8123** is a warning that appears when a tuple literal provides element names, but the target type expects different names or no names. Element names in a tuple literal are ignored during type conversion; assigning a named tuple to a variable of an unnamed or differently named tuple type does not copy the names. Rename the element names in the tuple literal to match the target type, or change the target type to preserve the intended names (**CS8123**). - -**CS8125** occurs when the reserved `ItemN` naming scheme is used but the name is placed at the wrong position. The names `Item1`, `Item2`, and so on are allowed only at their corresponding positions—`Item1` at position 1, `Item2` at position 2. For example, `(Item2: 2, Item1: 1)` is invalid because `Item2` is at position 1 and `Item1` is at position 2. Reorder the elements so that `ItemN` names correspond to their declared position, or use distinct custom names (**CS8125**). - -**CS8126** occurs when a tuple element uses a name that is reserved for the tuple's underlying `ValueTuple` infrastructure. Names such as `Rest`, `ToString`, `GetHashCode`, `Equals`, and members of `System.Runtime.CompilerServices.ITuple` cannot be used as element names. Choose a different element name (**CS8126**). - -**CS8127** occurs when two elements in the same tuple declaration use the same name. All element names within a tuple must be distinct. Rename one of the conflicting elements (**CS8127**): - -```csharp -internal struct NewStruct -{ - public int a; - public int b; - - // Error: both elements named 'a' - // public static implicit operator (int a, int a)(NewStruct value) => (value.a, value.b); - - // Fix: use distinct names - public static implicit operator (int a, int b)(NewStruct value) => (value.a, value.b); -} -``` +The compiler warns when tuple element names conflict with the target type or constraints. The compiler ignores names in tuple literals during type conversion. If the target type expects different names or no names, rename the tuple literal to match the target type or change the target type (**CS8123**). `ItemN` names are reserved for their specific positions (`Item1` at position 1, `Item2` at position 2, and so on). Reorder elements or use custom names (**CS8125**). Names like `Rest`, `ToString`, `GetHashCode`, and `Equals` are reserved for `ValueTuple` infrastructure and can't be used as element names. Choose a different name (**CS8126**). Ensure all element names within a tuple are distinct. Rename any duplicates (**CS8127**). ## Tuple element names in type hierarchy @@ -123,85 +95,14 @@ internal struct NewStruct - **CS8141**: *The tuple element names in the signature of method 'method' must match the tuple element names of interface method 'interface method' (including on the return type).* - **CS8142**: *Both partial member declarations, 'member' and 'other partial', must use the same tuple element names.* -Tuple element names are part of the method signature and must be consistent across overrides, interface implementations, and partial member declarations. - -**CS8139** occurs when an overriding method changes the tuple element names from those declared in the virtual or abstract base member. Match the tuple element names in the overriding method's signature to those in the base member (**CS8139**): - -```csharp -public class Base -{ - public virtual (object a, object b) M((object c, object d) x) { return x; } -} - -class Derived : Base -{ - // Error: return type changed 'a','b' to unnamed - // public override (object, object) M((object c, object d) y) { return y; } - - // Fix: preserve names from base - public override (object a, object b) M((object c, object d) y) { return y; } -} -``` - -**CS8140** occurs when a class implements the same generic interface twice through inheritance, but with different tuple element names. The class cannot satisfy both simultaneously. Align the tuple element names across all base types and interface implementations so that all paths to the same generic interface use the same element names (**CS8140**): - -```csharp -interface I -{ - T GetValue(); -} - -interface I2 : I<(int c, int d)> -{ -} - -// Error: I is implemented via I2 with (int c, int d), -// but also directly with (int a, int b) -// class C : I<(int a, int b)>, I2 -// { -// public (int c, int d) GetValue() => (1, 2); -// } - -// Fix: align element names across all paths to I -class C : I<(int c, int d)>, I2 -{ - public (int c, int d) GetValue() => (1, 2); -} -``` - -**CS8141** occurs when an explicit or implicit interface implementation uses different tuple element names than the interface member it implements. Match the tuple element names in the implementing method to those declared in the interface, for both parameters and return types (**CS8141**): - -```csharp -public interface IGrabber -{ - T GetOne(); -} - -// Error: implementation adds names to unnamed tuple -// class SomeGrabber : IGrabber<(int, int)> -// { -// public (int a, int b) GetOne() => (1, 2); -// } - -// Fix: match the interface's unnamed tuple -class SomeGrabber : IGrabber<(int, int)> -{ - public (int, int) GetOne() => (1, 2); -} -``` - -**CS8142** occurs when the two halves of a partial method or property declaration specify different tuple element names. Both declarations must use exactly the same tuple element names. Update one declaration to match the other (**CS8142**). +Tuple element names are part of method signatures and must be consistent across inheritance, interface implementation, and partial declarations. Match tuple element names in overriding methods to the base member (**CS8139**). Align element names across all base types and interface implementations so that all inheritance paths to the same generic interface use matching element names (**CS8140**). Match element names in interface implementations to the interface declaration, for both parameters and return types (**CS8141**). Update one partial declaration to match the other exactly (**CS8142**). ## Tuple metadata - **CS8137**: *Cannot define a class or member that utilizes tuples because the compiler required type 'type' cannot be found. Are you missing a reference?* - **CS8138**: *Cannot reference 'System.Runtime.CompilerServices.TupleElementNamesAttribute' explicitly. Use the tuple syntax to define tuple names.* -When a type signature includes named tuples, the compiler must be able to reference `TupleElementNamesAttribute` to store the element names in metadata. - -**CS8137** occurs when `TupleElementNamesAttribute` itself is missing from the referenced runtime. Ensure your project references a .NET runtime that provides `System.Runtime.CompilerServices.TupleElementNamesAttribute`. For older frameworks, add a reference to the `System.Runtime` NuGet package and rebuild (**CS8137**). - -**CS8138** occurs when source code explicitly references `[TupleElementNames(...)]`. This attribute is reserved for compiler use and cannot be applied in source. Use tuple literal syntax with element names—for example, `(int x, string y)`—and the compiler will generate the metadata automatically (**CS8138**). +When a type signature includes named tuples, the compiler must reference `TupleElementNamesAttribute` to store element names in metadata. Ensure your project references a .NET runtime that provides `System.Runtime.CompilerServices.TupleElementNamesAttribute`, or add the `System.Runtime` NuGet package for older frameworks (**CS8137**). Use tuple literal syntax with element names—for example, `(int x, string y)`—instead of explicitly referencing the attribute. The compiler generates the metadata automatically (**CS8138**). ## ValueTuple infrastructure @@ -209,87 +110,35 @@ When a type signature includes named tuples, the compiler must be able to refere - **CS8179**: *Predefined type 'type' is not defined or imported* - **CS8182**: *Predefined type 'type' must be a struct.* -These errors occur when the compiler cannot find or validate the required `System.ValueTuple` types that underlie tuple syntax. - -**CS8179** occurs when the `System.ValueTuple` type is completely absent. Tuples require this type. It is built into .NET Framework 4.7 and later, .NET Core, and .NET 5+. For older frameworks, add the `System.ValueTuple` NuGet package (**CS8179**). - -**CS8182** occurs when a `ValueTuple` type exists in the referenced assembly but is a class rather than a struct. The compiler requires it to be a struct. Verify that you are not shadowing the system `ValueTuple` types with a custom class in your project or a referenced assembly (**CS8182**). - -**CS8128** occurs when a specific member (such as `Item1`, `Item2`, or `Rest` for large tuples) is missing from the predefined `ValueTuple` type in the referenced assembly. This usually indicates an assembly mismatch or a corrupted custom `ValueTuple` implementation. Verify that your project references the correct version of the runtime or NuGet package (**CS8128**). +These errors occur when the compiler can't find or validate required `System.ValueTuple` types that underlie tuple syntax. Add the `System.ValueTuple` NuGet package for frameworks that don't include it built-in (for example, older .NET Framework versions) (**CS8179**). Verify that `ValueTuple` types are structs, not classes. If a custom class shadows system types, remove or rename it (**CS8182**). If a specific member (`Item1`, `Item2`, `Rest`) is missing from the predefined `ValueTuple` type, verify that your project references the correct runtime or NuGet package version (**CS8128**). ## Tuple structure and literals - **CS8124**: *Tuple must contain at least two elements.* - **CS8135**: *Tuple with 'count' elements cannot be converted to type 'type'.* -- **CS8181**: *'new' cannot be used with tuple type. Use a tuple literal expression instead.* - **CS8210**: *A tuple may not contain a value of type 'void'.* -These errors relate to how tuple expressions are formed. - -**CS8124** occurs when a tuple type or literal declares fewer than two elements. Tuples require at least two elements. Change a zero- or one-element tuple to use two or more elements (**CS8124**): - -```csharp -// Error: () and (int a) are invalid tuple types -// void M(int x, () y, (int a) z) { } - -// Fix: use at least two elements -void M(int x, (int, int) y, (int a, int b) z) { } -``` - -**CS8135** occurs when a tuple expression has a different number of elements than the target type expects. Ensure the tuple literal has the same element count as the destination type (**CS8135**). - -**CS8181** occurs when you write `new (T1, T2)(...)` using `new` with a tuple type. Tuple values are created with tuple literal syntax, not with `new`. Replace `new (T1, T2)(v1, v2)` with the literal `(v1, v2)` (**CS8181**). - -**CS8210** occurs when a tuple element expression evaluates to `void`—for example, by calling a `void`-returning method as a tuple element. Tuples can only contain values; they cannot hold a `void` result. Replace the `void` method call with an expression that produces a value, or redesign the tuple to exclude that element (**CS8210**): - -```csharp -void Method() -{ -} - -void Test() -{ - // Error: Method() returns void and cannot be a tuple element - // var x = ("something", Method()); -} -``` +These errors relate to tuple expression formation. Tuples require at least two elements; convert single-element or zero-element tuples to two or more elements (**CS8124**). Ensure tuple literals have the same element count as the destination type (**CS8135**). Remove `void`-returning method calls from tuple elements; tuples can only contain values, not `void` results (**CS8210**). ## Tuple type inference -- **CS8306**: *Tuple element name 'name' is inferred. Please use language version 7.1 or greater to access an element by its inferred name.* - **CS8307**: *The first operand of an 'as' operator may not be a tuple literal without a natural type.* -**CS8306** occurs when code accesses an inferred tuple element name—a name derived from a variable or member expression, such as `(x, y).x`—but the project targets a language version earlier than C# 7.1. To resolve, set `7.1` or higher in your project file, or access the element by position (`Item1`, `Item2`) instead of its inferred name (**CS8306**). - -**CS8307** occurs when a tuple literal without explicit element types is used as the left operand of an `as` operator. The `as` operator requires type information, and a bare tuple literal has no natural type. Either assign the literal to a typed variable first, then apply `as` to the variable, or annotate the tuple with an explicit type before using `as` (**CS8307**). +**CS8307** occurs when a tuple literal without explicit element types is used as the left operand of an `as` operator. Assign the literal to a typed variable first, then apply `as` to the variable, or annotate the tuple with an explicit type before using `as` (**CS8307**). ## Tuple equality - **CS8383**: *The tuple element name 'name' is ignored because a different name or no name is specified on the other side of the tuple == or != operator.* - **CS8384**: *Tuple types used as operands of an == or != operator must have matching cardinalities. But this operator has tuple types of cardinality 'left' on the left and 'right' on the right.* -**CS8383** is a warning that appears when the two operands of a `==` or `!=` comparison have different or absent element names. Element names do not affect equality semantics—the comparison still compares element values positionally—but the mismatch often indicates a naming inconsistency. Align the element names on both sides of the operator, or use unnamed tuples if the names are not meaningful for this comparison (**CS8383**). - -**CS8384** occurs when the two operands of a `==` or `!=` comparison have different numbers of elements. Tuples of different sizes are not comparable. Adjust the tuple literals or types so that both operands have the same element count (**CS8384**). +**CS8383** is a warning when `==` or `!=` operands have different or absent element names. Names don't affect equality semantics (comparison is positional), but mismatches often indicate naming inconsistency. Align element names on both sides or use unnamed tuples (**CS8383**). **CS8384** occurs when `==` or `!=` operands have different numbers of elements. Adjust tuple literals or types so both operands have the same element count (**CS8384**). ## Pattern matching with tuples - **CS8516**: *The name 'name' does not identify tuple element 'element'.* - **CS8522**: *Element names are not permitted when pattern-matching via 'System.Runtime.CompilerServices.ITuple'.* -**CS8516** occurs when a tuple pattern uses a property name that does not match any element name of the tuple type being matched. Tuple patterns match elements by name; check the element names of the tuple type and correct the pattern property name (**CS8516**): - -```csharp -var point = (x: 1, y: 2); - -// Error: 'a' and 'b' do not identify elements of (int x, int y) -// if (point is (a: 1, b: _)) { } - -// Fix: use the declared element names -if (point is (x: 1, y: _)) { } -``` - -**CS8522** occurs when a positional pattern uses named subpatterns against a type that implements `System.Runtime.CompilerServices.ITuple` but is not a known tuple type. When pattern-matching via the `ITuple` interface, elements must be matched positionally, not by name. Remove the element names from the pattern (**CS8522**). +**CS8516** occurs when a tuple pattern uses a property name that doesn't match any element of the tuple type. Verify the element names of the tuple type and correct the pattern property name. **CS8522** occurs when a positional pattern uses named subpatterns against a type that implements `System.Runtime.CompilerServices.ITuple` but isn't a known tuple type. Remove element names from the pattern and match positionally. ## See also diff --git a/docs/csharp/language-reference/toc.yml b/docs/csharp/language-reference/toc.yml index 4aee87becdf0b..78596fdc0de3a 100644 --- a/docs/csharp/language-reference/toc.yml +++ b/docs/csharp/language-reference/toc.yml @@ -523,8 +523,8 @@ items: displayName: > tuples, tuple element names, tuple metadata, tuple conversions, tuple equality, tuple pattern matching, CS8123, CS8124, CS8125, CS8126, CS8127, CS8128, CS8135, CS8137, CS8138, CS8139, - CS8140, CS8141, CS8142, CS8179, CS8181, CS8182, CS8210, CS8306, CS8307, CS8383, - CS8384, CS8516, CS8522 + CS8140, CS8141, CS8142, CS8179, CS8182, CS8210, CS8307, CS8383, CS8384, CS8516, + CS8522 - name: Record declarations href: ./compiler-messages/record-declaration-errors.md displayName: > From ec3c98b12a12c895751f4b1f349d36ca8a3adbe5 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Mon, 17 Aug 2026 16:36:18 -0400 Subject: [PATCH 4/7] Style fixes Add periods as needed. Quote metadata. --- .../compiler-messages/tuple-errors.md | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/docs/csharp/language-reference/compiler-messages/tuple-errors.md b/docs/csharp/language-reference/compiler-messages/tuple-errors.md index d3ee426352b23..c2410f1bfffe7 100644 --- a/docs/csharp/language-reference/compiler-messages/tuple-errors.md +++ b/docs/csharp/language-reference/compiler-messages/tuple-errors.md @@ -1,50 +1,50 @@ --- title: "Resolve errors and warnings related to tuples" -description: "This article helps you diagnose and correct compiler errors and warnings related to tuple declarations, element names, metadata, conversions, equality, type inference, and pattern matching" +description: "This article helps you diagnose and correct compiler errors and warnings related to tuple declarations, element names, metadata, conversions, equality, type inference, and pattern matching." f1_keywords: - - CS8123 - - CS8124 - - CS8125 - - CS8126 - - CS8127 - - CS8128 - - CS8135 - - CS8137 - - CS8138 - - CS8139 - - CS8140 - - CS8141 - - CS8142 - - CS8179 - - CS8182 - - CS8210 - - CS8307 - - CS8383 - - CS8384 - - CS8516 - - CS8522 + - "CS8123" + - "CS8124" + - "CS8125" + - "CS8126" + - "CS8127" + - "CS8128" + - "CS8135" + - "CS8137" + - "CS8138" + - "CS8139" + - "CS8140" + - "CS8141" + - "CS8142" + - "CS8179" + - "CS8182" + - "CS8210" + - "CS8307" + - "CS8383" + - "CS8384" + - "CS8516" + - "CS8522" helpviewer_keywords: - - CS8123 - - CS8124 - - CS8125 - - CS8126 - - CS8127 - - CS8128 - - CS8135 - - CS8137 - - CS8138 - - CS8139 - - CS8140 - - CS8141 - - CS8142 - - CS8179 - - CS8182 - - CS8210 - - CS8307 - - CS8383 - - CS8384 - - CS8516 - - CS8522 + - "CS8123" + - "CS8124" + - "CS8125" + - "CS8126" + - "CS8127" + - "CS8128" + - "CS8135" + - "CS8137" + - "CS8138" + - "CS8139" + - "CS8140" + - "CS8141" + - "CS8142" + - "CS8179" + - "CS8182" + - "CS8210" + - "CS8307" + - "CS8383" + - "CS8384" + - "CS8516" + - "CS8522" ms.date: 08/17/2026 ai-usage: ai-assisted --- @@ -107,7 +107,7 @@ When a type signature includes named tuples, the compiler must reference `TupleE ## ValueTuple infrastructure - **CS8128**: *Member 'member' was not found on type 'type' from assembly 'assembly'.* -- **CS8179**: *Predefined type 'type' is not defined or imported* +- **CS8179**: *Predefined type 'type' is not defined or imported.* - **CS8182**: *Predefined type 'type' must be a struct.* These errors occur when the compiler can't find or validate required `System.ValueTuple` types that underlie tuple syntax. Add the `System.ValueTuple` NuGet package for frameworks that don't include it built-in (for example, older .NET Framework versions) (**CS8179**). Verify that `ValueTuple` types are structs, not classes. If a custom class shadows system types, remove or rename it (**CS8182**). If a specific member (`Item1`, `Item2`, `Rest`) is missing from the predefined `ValueTuple` type, verify that your project references the correct runtime or NuGet package version (**CS8128**). From 6562cba0df4debf89d9edcc0933d2f9e6fa390ba Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Mon, 17 Aug 2026 16:37:33 -0400 Subject: [PATCH 5/7] lint --- docs/csharp/language-reference/compiler-messages/tuple-errors.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/csharp/language-reference/compiler-messages/tuple-errors.md b/docs/csharp/language-reference/compiler-messages/tuple-errors.md index c2410f1bfffe7..7393281bf090a 100644 --- a/docs/csharp/language-reference/compiler-messages/tuple-errors.md +++ b/docs/csharp/language-reference/compiler-messages/tuple-errors.md @@ -146,4 +146,3 @@ These errors relate to tuple expression formation. Tuples require at least two e - [Deconstruction](../../fundamentals/functional/deconstruct.md) - [Pattern matching](../../fundamentals/functional/pattern-matching.md) - [Void](../builtin-types/void.md) - From cba56ac4eb638c2abfa040450328b002dade0d24 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Tue, 18 Aug 2026 10:47:46 -0400 Subject: [PATCH 6/7] Apply suggestions from code review Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> --- .../language-reference/compiler-messages/tuple-errors.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/csharp/language-reference/compiler-messages/tuple-errors.md b/docs/csharp/language-reference/compiler-messages/tuple-errors.md index 7393281bf090a..1c8811fb55905 100644 --- a/docs/csharp/language-reference/compiler-messages/tuple-errors.md +++ b/docs/csharp/language-reference/compiler-messages/tuple-errors.md @@ -110,7 +110,7 @@ When a type signature includes named tuples, the compiler must reference `TupleE - **CS8179**: *Predefined type 'type' is not defined or imported.* - **CS8182**: *Predefined type 'type' must be a struct.* -These errors occur when the compiler can't find or validate required `System.ValueTuple` types that underlie tuple syntax. Add the `System.ValueTuple` NuGet package for frameworks that don't include it built-in (for example, older .NET Framework versions) (**CS8179**). Verify that `ValueTuple` types are structs, not classes. If a custom class shadows system types, remove or rename it (**CS8182**). If a specific member (`Item1`, `Item2`, `Rest`) is missing from the predefined `ValueTuple` type, verify that your project references the correct runtime or NuGet package version (**CS8128**). +These errors occur when the compiler can't find or validate required types that underlie tuple syntax. Add the `System.ValueTuple` NuGet package for frameworks that don't include it built-in (for example, older .NET Framework versions) (**CS8179**). Verify that `ValueTuple` types are structs, not classes. If a custom class shadows system types, remove or rename it (**CS8182**). If a specific member (`Item1`, `Item2`, `Rest`) is missing from the predefined `ValueTuple` type, verify that your project references the correct runtime or NuGet package version (**CS8128**). ## Tuple structure and literals @@ -138,7 +138,7 @@ These errors relate to tuple expression formation. Tuples require at least two e - **CS8516**: *The name 'name' does not identify tuple element 'element'.* - **CS8522**: *Element names are not permitted when pattern-matching via 'System.Runtime.CompilerServices.ITuple'.* -**CS8516** occurs when a tuple pattern uses a property name that doesn't match any element of the tuple type. Verify the element names of the tuple type and correct the pattern property name. **CS8522** occurs when a positional pattern uses named subpatterns against a type that implements `System.Runtime.CompilerServices.ITuple` but isn't a known tuple type. Remove element names from the pattern and match positionally. +**CS8516** occurs when a tuple pattern uses a property name that doesn't match any element of the tuple type. Verify the element names of the tuple type and correct the pattern property name. **CS8522** occurs when a positional pattern uses named subpatterns against a type that implements but isn't a known tuple type. Remove element names from the pattern and match positionally. ## See also From ab0d9222aae13648c48d7bc61b51a55290ff35cc Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Tue, 18 Aug 2026 10:53:08 -0400 Subject: [PATCH 7/7] Use xrefs --- .../csharp/language-reference/compiler-messages/tuple-errors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/csharp/language-reference/compiler-messages/tuple-errors.md b/docs/csharp/language-reference/compiler-messages/tuple-errors.md index 1c8811fb55905..54b58e2bd7772 100644 --- a/docs/csharp/language-reference/compiler-messages/tuple-errors.md +++ b/docs/csharp/language-reference/compiler-messages/tuple-errors.md @@ -102,7 +102,7 @@ Tuple element names are part of method signatures and must be consistent across - **CS8137**: *Cannot define a class or member that utilizes tuples because the compiler required type 'type' cannot be found. Are you missing a reference?* - **CS8138**: *Cannot reference 'System.Runtime.CompilerServices.TupleElementNamesAttribute' explicitly. Use the tuple syntax to define tuple names.* -When a type signature includes named tuples, the compiler must reference `TupleElementNamesAttribute` to store element names in metadata. Ensure your project references a .NET runtime that provides `System.Runtime.CompilerServices.TupleElementNamesAttribute`, or add the `System.Runtime` NuGet package for older frameworks (**CS8137**). Use tuple literal syntax with element names—for example, `(int x, string y)`—instead of explicitly referencing the attribute. The compiler generates the metadata automatically (**CS8138**). +When a type signature includes named tuples, the compiler must reference to store element names in metadata. Ensure your project references a .NET runtime that provides , or add the `System.Runtime` NuGet package for older frameworks (**CS8137**). Use tuple literal syntax with element names—for example, `(int x, string y)`—instead of explicitly referencing the attribute. The compiler generates the metadata automatically (**CS8138**). ## ValueTuple infrastructure