From 2288d13cf8fde7dc912bf55f00db57daea10e6b1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Jun 2025 21:07:34 +0000 Subject: [PATCH 1/4] Initial plan for issue From d8238d31c294571a6b2423f7718b58bfd88b54aa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Jun 2025 21:11:23 +0000 Subject: [PATCH 2/4] Update CS0460 documentation to include C# 8/9 constraint exceptions Co-authored-by: BillWagner <493969+BillWagner@users.noreply.github.com> --- docs/csharp/misc/cs0460.md | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/docs/csharp/misc/cs0460.md b/docs/csharp/misc/cs0460.md index c80da435b4d9d..e838e5ca3e07e 100644 --- a/docs/csharp/misc/cs0460.md +++ b/docs/csharp/misc/cs0460.md @@ -1,7 +1,7 @@ --- description: "Compiler Error CS0460" title: "Compiler Error CS0460" -ms.date: 07/20/2015 +ms.date: 01/02/2025 f1_keywords: - "CS0460" helpviewer_keywords: @@ -10,13 +10,17 @@ ms.assetid: 98d39ded-d3f9-4520-b912-892e574c056b --- # Compiler Error CS0460 -Constraints for override and explicit interface implementation methods are inherited from the base method, so they cannot be specified directly +Constraints for override and explicit interface implementation methods are inherited from the base method, so they cannot be specified directly, except in specific cases When a generic method that is part of a derived class overrides a method in the base class, you may not specify constraints on the overridden method. The override method in the derived class inherits its constraints from the method in the base class. + However, there are exceptions to this rule: + - Starting with C# 9, you can apply the `default` constraint to override and explicit interface implementation methods to resolve ambiguities with nullable reference types. + - Starting with C# 8, you can explicitly specify `where T : class` and `where T : struct` constraints on override and explicit interface implementation methods to allow annotations for type parameters constrained to reference types. + ## Example - The following sample generates CS0460. + The following sample generates CS0460 when attempting to redeclare inherited constraints. ```csharp // CS0460.cs @@ -30,12 +34,19 @@ interface I { void F1() where T : BaseClass; void F2() where T : struct; - void F3() where T : BaseClass; + void F3(); + void F4() where T : struct; } class ExpImpl : I { - void I.F1() where T : BaseClass {} // CS0460 - void I.F2() where T : class {} // CS0460 + void I.F1() where T : BaseClass {} // CS0460 - cannot redeclare inherited constraint + void I.F2() where T : struct {} // CS0460 - cannot redeclare inherited constraint + + // Valid since C# 8 - explicit class constraint for nullable annotations + void I.F4() where T : class {} // OK - explicit constraint for nullable annotations + + // Valid since C# 9 - default constraint to resolve ambiguities + void I.F3() where T : default {} // OK - default constraint } ``` From 485c1b227adef52228a3002fb5798513debee7b6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 3 Jun 2025 14:30:06 +0000 Subject: [PATCH 3/4] Address PR feedback: Update metadata, revert verbatim error message, fix code sample Co-authored-by: BillWagner <493969+BillWagner@users.noreply.github.com> --- docs/csharp/misc/cs0460.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/docs/csharp/misc/cs0460.md b/docs/csharp/misc/cs0460.md index e838e5ca3e07e..be8c7acae5394 100644 --- a/docs/csharp/misc/cs0460.md +++ b/docs/csharp/misc/cs0460.md @@ -1,7 +1,8 @@ --- description: "Compiler Error CS0460" title: "Compiler Error CS0460" -ms.date: 01/02/2025 +ms.date: 06/03/2025 +ai-usage: ai-generated f1_keywords: - "CS0460" helpviewer_keywords: @@ -10,13 +11,14 @@ ms.assetid: 98d39ded-d3f9-4520-b912-892e574c056b --- # Compiler Error CS0460 -Constraints for override and explicit interface implementation methods are inherited from the base method, so they cannot be specified directly, except in specific cases +Constraints for override and explicit interface implementation methods are inherited from the base method, so they cannot be specified directly When a generic method that is part of a derived class overrides a method in the base class, you may not specify constraints on the overridden method. The override method in the derived class inherits its constraints from the method in the base class. - However, there are exceptions to this rule: - - Starting with C# 9, you can apply the `default` constraint to override and explicit interface implementation methods to resolve ambiguities with nullable reference types. - - Starting with C# 8, you can explicitly specify `where T : class` and `where T : struct` constraints on override and explicit interface implementation methods to allow annotations for type parameters constrained to reference types. +However, there are exceptions to this rule: + +- Starting with C# 9, you can apply the `default` constraint to override and explicit interface implementation methods to resolve ambiguities with nullable reference types. +- Starting with C# 8, you can explicitly specify `where T : class` and `where T : struct` constraints on override and explicit interface implementation methods to allow annotations for type parameters constrained to reference types. ## Example @@ -40,13 +42,13 @@ interface I class ExpImpl : I { - void I.F1() where T : BaseClass {} // CS0460 - cannot redeclare inherited constraint - void I.F2() where T : struct {} // CS0460 - cannot redeclare inherited constraint - - // Valid since C# 8 - explicit class constraint for nullable annotations - void I.F4() where T : class {} // OK - explicit constraint for nullable annotations + void I.F1() where T : BaseClass { } // CS0460 - cannot redeclare inherited constraint + void I.F2() where T : struct { } // allowed - explicit constraint for struct - // Valid since C# 9 - default constraint to resolve ambiguities - void I.F3() where T : default {} // OK - default constraint -} + // Valid since C# 8 - explicit class constraint for nullable annotations + void I.F4() where T : struct { } // OK - explicit constraint for nullable annotations + + // Valid since C# 9 - default constraint to resolve ambiguities + void I.F3() where T : default { } // OK - default constraint +} ``` From 40001c075099c655579155960a43159dcaebcf56 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 3 Jun 2025 21:56:32 +0000 Subject: [PATCH 4/4] Address PR review feedback: improve clarity and format code comments Co-authored-by: gewarren <24882762+gewarren@users.noreply.github.com> --- docs/csharp/misc/cs0460.md | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/docs/csharp/misc/cs0460.md b/docs/csharp/misc/cs0460.md index be8c7acae5394..93633a953186f 100644 --- a/docs/csharp/misc/cs0460.md +++ b/docs/csharp/misc/cs0460.md @@ -13,12 +13,12 @@ ms.assetid: 98d39ded-d3f9-4520-b912-892e574c056b Constraints for override and explicit interface implementation methods are inherited from the base method, so they cannot be specified directly - When a generic method that is part of a derived class overrides a method in the base class, you may not specify constraints on the overridden method. The override method in the derived class inherits its constraints from the method in the base class. + When a generic method that is part of a derived class overrides a method in the base class, you can't specify constraints on the overridden method. The override method in the derived class inherits its constraints from the method in the base class. However, there are exceptions to this rule: -- Starting with C# 9, you can apply the `default` constraint to override and explicit interface implementation methods to resolve ambiguities with nullable reference types. -- Starting with C# 8, you can explicitly specify `where T : class` and `where T : struct` constraints on override and explicit interface implementation methods to allow annotations for type parameters constrained to reference types. +- Starting with C# 9, you can apply the `default` constraint to `override` and explicit interface implementation methods to resolve ambiguities with nullable reference types. +- Starting with C# 8, you can explicitly specify `where T : class` and `where T : struct` constraints on `override` and explicit interface implementation methods to allow annotations for type parameters constrained to reference types. ## Example @@ -42,13 +42,16 @@ interface I class ExpImpl : I { - void I.F1() where T : BaseClass { } // CS0460 - cannot redeclare inherited constraint - void I.F2() where T : struct { } // allowed - explicit constraint for struct + // CS0460 - cannot redeclare inherited constraint. + void I.F1() where T : BaseClass { } + + // Allowed - explicit constraint for struct. + void I.F2() where T : struct { } - // Valid since C# 8 - explicit class constraint for nullable annotations - void I.F4() where T : struct { } // OK - explicit constraint for nullable annotations - - // Valid since C# 9 - default constraint to resolve ambiguities - void I.F3() where T : default { } // OK - default constraint + // Valid since C# 8 - explicit class constraint for nullable annotations. + void I.F4() where T : struct { } + + // Valid since C# 9 - default constraint to resolve ambiguities. + void I.F3() where T : default { } } ```