The compiler has to turn your method into a resumable state machine. Some shapes cannot be resumed, and those are exactly the ones it refuses.
| You cannot | Because |
|---|---|
yield inside a try that has a catch | Resuming into a half-finished catch has no meaning |
yield inside a lambda or anonymous method | Those are not iterators; only a named method can be one |
yield in a method with ref or out parameters | The parameters would be long gone by the time the body resumes |
yield in an unsafe block | The state machine would have to preserve pointers across a pause |
return someValue; | The method reports values only through yield return |
A try with only a finally is allowed, and so is a try/catch that contains no yield.
Parsing that may fail
Rejected
C#
static IEnumerable<int> Parsed(
string[] items)
{
foreach (var s in items)
{
try
{
yield return int.Parse(s);
// CS1626: cannot yield inside
// a try with a catch
}
catch (FormatException)
{
}
}
}Accepted
C#
static IEnumerable<int> Parsed(
string[] items)
{
foreach (var s in items)
{
int value;
if (!int.TryParse(s, out value))
{
continue;
}
yield return value;
}
}Do the risky work into a local, outside any yield, and yield afterwards. Where a Try... method exists, it is usually the cleanest way out.
Try it: Task 2
Open the editor