From d6f801ab09cf17dde11b066f3a7ab8c6a3d987d3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 Aug 2025 19:28:22 +0000 Subject: [PATCH 1/2] Initial plan From 317dc61263a7d1b1946770257b08dd4485d11768 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 Aug 2025 19:35:56 +0000 Subject: [PATCH 2/2] Add comprehensive CS1622 error documentation with iterator method rules Co-authored-by: BillWagner <493969+BillWagner@users.noreply.github.com> --- docs/csharp/misc/cs1622.md | 169 +++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 docs/csharp/misc/cs1622.md diff --git a/docs/csharp/misc/cs1622.md b/docs/csharp/misc/cs1622.md new file mode 100644 index 0000000000000..a3f2c39293b6b --- /dev/null +++ b/docs/csharp/misc/cs1622.md @@ -0,0 +1,169 @@ +--- +description: "Compiler Error CS1622" +title: "Compiler Error CS1622" +ms.date: 12/19/2024 +f1_keywords: + - "CS1622" +helpviewer_keywords: + - "CS1622" +ms.assetid: 6b53a777-4cd8-423a-84ff-22ff588044d3 +--- +# Compiler Error CS1622 + +Cannot return a value from an iterator. Use the yield return statement to return a value, or yield break to end the iteration. + +This error occurs when you try to use a `return` statement to return a value inside an iterator method that uses `yield return` statements. Iterator methods have specific rules about how values are returned. + +## Understanding the error + +The CS1622 error indicates a violation of iterator method rules. There are two scenarios to understand: + +### Scenario 1: Mixing `yield return` with `return` (causes CS1622) + +You cannot mix `yield return` statements with `return` statements that return values in the same iterator method: + +```csharp +// CS1622 - This is invalid +public static IEnumerable GetNumbers() +{ + yield return 1; + yield return 2; + return new[] { 3, 4, 5 }; // CS1622: Cannot return a value from an iterator +} +``` + +### Scenario 2: Returning an object that implements the interface (allowed) + +However, you *can* use a single `return` statement to return an object that implements the required interface, as long as you don't use any `yield` statements: + +```csharp +// This is valid - no yield statements, just returning an object that implements IEnumerable +public static IEnumerable GetNumbers() +{ + return new[] { 1, 2, 3, 4, 5 }; // Valid +} + +// This is also valid +public static IEnumerable GetNumbersConditionally(bool useArray) +{ + if (useArray) + return new[] { 1, 2, 3 }; // Valid + else + return new List { 4, 5, 6 }; // Valid +} +``` + +## How to fix CS1622 + +### Fix 1: Use only `yield return` and `yield break` + +Convert your method to use only yield statements: + +```csharp +// Corrected version using only yield statements +public static IEnumerable GetNumbers() +{ + yield return 1; + yield return 2; + // Instead of return new[] { 3, 4, 5 }; + foreach (int num in new[] { 3, 4, 5 }) + { + yield return num; + } +} +``` + +### Fix 2: Use only `return` statements (no yield) + +If you want to return pre-computed collections, avoid yield statements entirely: + +```csharp +// Corrected version using only return statements +public static IEnumerable GetNumbers() +{ + var firstPart = new[] { 1, 2 }; + var secondPart = new[] { 3, 4, 5 }; + return firstPart.Concat(secondPart); +} +``` + +### Fix 3: Split into separate methods + +Split the logic into separate methods: + +```csharp +public static IEnumerable GetNumbers() +{ + // Yield the first part + foreach (int num in GetFirstPart()) + { + yield return num; + } + + // Yield the second part + foreach (int num in GetSecondPart()) + { + yield return num; + } +} + +private static IEnumerable GetFirstPart() +{ + yield return 1; + yield return 2; +} + +private static IEnumerable GetSecondPart() +{ + return new[] { 3, 4, 5 }; +} +``` + +## IAsyncEnumerable<T> considerations + +The same rules apply to async iterator methods that return `IAsyncEnumerable`: + +```csharp +// CS1622 - Cannot mix yield return with return in async iterators +public static async IAsyncEnumerable GetNumbersAsync() +{ + yield return 1; + await Task.Delay(100); + yield return 2; + return new[] { 3, 4, 5 }; // CS1622: Cannot return a value from an iterator +} + +// Valid - using only yield return in async iterator +public static async IAsyncEnumerable GetNumbersAsync() +{ + yield return 1; + await Task.Delay(100); + yield return 2; + foreach (int num in new[] { 3, 4, 5 }) + { + yield return num; + } +} + +// Valid - returning an IAsyncEnumerable implementation +public static IAsyncEnumerable GetNumbersAsync() +{ + return GetAsyncEnumerable(); + + static async IAsyncEnumerable GetAsyncEnumerable() + { + yield return 1; + await Task.Delay(100); + yield return 2; + yield return 3; + } +} +``` + +## Related errors + +- [CS1624](../language-reference/compiler-messages/iterator-yield.md): The body of 'accessor' cannot be an iterator block because 'type' is not an iterator interface type +- [CS1625](../language-reference/compiler-messages/iterator-yield.md): Cannot yield in the body of a finally clause +- [CS1626](../language-reference/compiler-messages/iterator-yield.md): Cannot yield a value in the body of a try block with a catch clause + +For more information about iterator methods and yield statements, see [Iterators](../programming-guide/concepts/iterators.md) and [Iterator methods and yield return](../language-reference/compiler-messages/iterator-yield.md).