Skip to content

Commit 317dc61

Browse files
CopilotBillWagner
andcommitted
Add comprehensive CS1622 error documentation with iterator method rules
Co-authored-by: BillWagner <[email protected]>
1 parent d6f801a commit 317dc61

File tree

1 file changed

+169
-0
lines changed

1 file changed

+169
-0
lines changed

docs/csharp/misc/cs1622.md

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
---
2+
description: "Compiler Error CS1622"
3+
title: "Compiler Error CS1622"
4+
ms.date: 12/19/2024
5+
f1_keywords:
6+
- "CS1622"
7+
helpviewer_keywords:
8+
- "CS1622"
9+
ms.assetid: 6b53a777-4cd8-423a-84ff-22ff588044d3
10+
---
11+
# Compiler Error CS1622
12+
13+
Cannot return a value from an iterator. Use the yield return statement to return a value, or yield break to end the iteration.
14+
15+
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.
16+
17+
## Understanding the error
18+
19+
The CS1622 error indicates a violation of iterator method rules. There are two scenarios to understand:
20+
21+
### Scenario 1: Mixing `yield return` with `return` (causes CS1622)
22+
23+
You cannot mix `yield return` statements with `return` statements that return values in the same iterator method:
24+
25+
```csharp
26+
// CS1622 - This is invalid
27+
public static IEnumerable<int> GetNumbers()
28+
{
29+
yield return 1;
30+
yield return 2;
31+
return new[] { 3, 4, 5 }; // CS1622: Cannot return a value from an iterator
32+
}
33+
```
34+
35+
### Scenario 2: Returning an object that implements the interface (allowed)
36+
37+
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:
38+
39+
```csharp
40+
// This is valid - no yield statements, just returning an object that implements IEnumerable<int>
41+
public static IEnumerable<int> GetNumbers()
42+
{
43+
return new[] { 1, 2, 3, 4, 5 }; // Valid
44+
}
45+
46+
// This is also valid
47+
public static IEnumerable<int> GetNumbersConditionally(bool useArray)
48+
{
49+
if (useArray)
50+
return new[] { 1, 2, 3 }; // Valid
51+
else
52+
return new List<int> { 4, 5, 6 }; // Valid
53+
}
54+
```
55+
56+
## How to fix CS1622
57+
58+
### Fix 1: Use only `yield return` and `yield break`
59+
60+
Convert your method to use only yield statements:
61+
62+
```csharp
63+
// Corrected version using only yield statements
64+
public static IEnumerable<int> GetNumbers()
65+
{
66+
yield return 1;
67+
yield return 2;
68+
// Instead of return new[] { 3, 4, 5 };
69+
foreach (int num in new[] { 3, 4, 5 })
70+
{
71+
yield return num;
72+
}
73+
}
74+
```
75+
76+
### Fix 2: Use only `return` statements (no yield)
77+
78+
If you want to return pre-computed collections, avoid yield statements entirely:
79+
80+
```csharp
81+
// Corrected version using only return statements
82+
public static IEnumerable<int> GetNumbers()
83+
{
84+
var firstPart = new[] { 1, 2 };
85+
var secondPart = new[] { 3, 4, 5 };
86+
return firstPart.Concat(secondPart);
87+
}
88+
```
89+
90+
### Fix 3: Split into separate methods
91+
92+
Split the logic into separate methods:
93+
94+
```csharp
95+
public static IEnumerable<int> GetNumbers()
96+
{
97+
// Yield the first part
98+
foreach (int num in GetFirstPart())
99+
{
100+
yield return num;
101+
}
102+
103+
// Yield the second part
104+
foreach (int num in GetSecondPart())
105+
{
106+
yield return num;
107+
}
108+
}
109+
110+
private static IEnumerable<int> GetFirstPart()
111+
{
112+
yield return 1;
113+
yield return 2;
114+
}
115+
116+
private static IEnumerable<int> GetSecondPart()
117+
{
118+
return new[] { 3, 4, 5 };
119+
}
120+
```
121+
122+
## IAsyncEnumerable&lt;T&gt; considerations
123+
124+
The same rules apply to async iterator methods that return `IAsyncEnumerable<T>`:
125+
126+
```csharp
127+
// CS1622 - Cannot mix yield return with return in async iterators
128+
public static async IAsyncEnumerable<int> GetNumbersAsync()
129+
{
130+
yield return 1;
131+
await Task.Delay(100);
132+
yield return 2;
133+
return new[] { 3, 4, 5 }; // CS1622: Cannot return a value from an iterator
134+
}
135+
136+
// Valid - using only yield return in async iterator
137+
public static async IAsyncEnumerable<int> GetNumbersAsync()
138+
{
139+
yield return 1;
140+
await Task.Delay(100);
141+
yield return 2;
142+
foreach (int num in new[] { 3, 4, 5 })
143+
{
144+
yield return num;
145+
}
146+
}
147+
148+
// Valid - returning an IAsyncEnumerable implementation
149+
public static IAsyncEnumerable<int> GetNumbersAsync()
150+
{
151+
return GetAsyncEnumerable();
152+
153+
static async IAsyncEnumerable<int> GetAsyncEnumerable()
154+
{
155+
yield return 1;
156+
await Task.Delay(100);
157+
yield return 2;
158+
yield return 3;
159+
}
160+
}
161+
```
162+
163+
## Related errors
164+
165+
- [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
166+
- [CS1625](../language-reference/compiler-messages/iterator-yield.md): Cannot yield in the body of a finally clause
167+
- [CS1626](../language-reference/compiler-messages/iterator-yield.md): Cannot yield a value in the body of a try block with a catch clause
168+
169+
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).

0 commit comments

Comments
 (0)