方法的返回类型必须是
确切地
其中之一
IEnumerable
,
IEnumerable<T>
,
IEnumerator
或
IEnumerator<T>
,而不是
T
,是实现的某种类型
IEnumerable<U>
。
这是因为迭代器方法的工作方式是,编译器生成一个实现上述接口之一的类型
MoveNext
和
Current
正确实现,使其与方法的行为匹配,然后重写方法以返回该类型的实例。
例如,对于:
public IEnumerable<int> GetSingleDigitNumbersLoop()
{
int index = 0;
while (index < 10)
yield return index++;
}
生成以下内容(使用
SharpLab.io
):
[IteratorStateMachine(typeof(<GetSingleDigitNumbersLoop>d__0))]
public IEnumerable<int> GetSingleDigitNumbersLoop()
{
return new <GetSingleDigitNumbersLoop>d__0(-2);
}
[CompilerGenerated]
private sealed class <GetSingleDigitNumbersLoop>d__0 : IEnumerable<int>, IEnumerable, IEnumerator<int>, IDisposable, IEnumerator
{
private int <>1__state;
private int <>2__current;
private int <>l__initialThreadId;
private int <index>5__2;
int IEnumerator<int>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <GetSingleDigitNumbersLoop>d__0(int <>1__state)
{
this.<>1__state = <>1__state;
<>l__initialThreadId = Environment.CurrentManagedThreadId;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
}
private bool MoveNext()
{
int num = <>1__state;
if (num != 0)
{
if (num != 1)
{
return false;
}
<>1__state = -1;
}
else
{
<>1__state = -1;
<index>5__2 = 0;
}
if (<index>5__2 < 10)
{
<>2__current = <index>5__2++;
<>1__state = 1;
return true;
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
[DebuggerHidden]
IEnumerator<int> IEnumerable<int>.GetEnumerator()
{
if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
{
<>1__state = 0;
return this;
}
return new <GetSingleDigitNumbersLoop>d__0(0);
}
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<int>)this).GetEnumerator();
}
}
<GetSingleDigitNumbersLoop>d__0
是实现的类型
IEnumerable<int>
那个
GetSingleDigitNumbersLoop
被重写为返回。
现在,如果
GetSingleDigitNumbersLoop
被声明为返回其他类型,如类型参数
T
例如,以下操作不起作用:
public T GetSingleDigitNumbersLoop()
{
return new <GetSingleDigitNumbersLoop>d__0(-2);
}
因为
<GetSingleDigitNumbersLoop>d_0
不一定是
T
。事实上,它几乎永远不会,因为它是编译器生成的类型!
另请参阅:
yield statement implementation