yield一般有两种形式yield retrun和yield break
为了区别yield retrun和yield break
分别声明了两个方法
public static IEnumerable PowerReturn(int baseNumber, int highExponent)
{
int result = 1;
for (int counter = 1; counter <= highExponent; counter++)
{
result = result * baseNumber;
yield return result;
}
}
public static IEnumerable PowerBreak(int baseNumber, int highExponent)
{
int result = 1;
for (int counter = 1; counter <= highExponent; counter++)
{
result = result * baseNumber;
yield break;
}
}
分别枚举里面的数据的时候yield retrun返回迭代其当前的数据
yield break直接跳出了循环
foreach (int number in Power(2, 8))
{
Console.WriteLine(number.ToString() + " ");
}
MoveNext方法经过反汇编之后发现.net会为迭代器生成私有的类,标记为yield return的方法会在内部类用全局变量保存迭代的结果和当前迭代的数值,而yield break会在MoveNext方法内部定义保存迭代结果的值和当前迭代数值并且直接跳出循环数据不会返回,下面是两个方法对比
private bool MoveNext()
{
.locals init (
[0] int32 CS$0$0000)
L_0000: ldarg.0
L_0001: ldfld int32 testdiedai.Program/<Power>d__0::<>1__state
L_0006: stloc.0
L_0007: ldloc.0
L_0008: switch (L_0017, L_005b)
L_0015: br.s L_007e
L_0017: ldarg.0
L_0018: ldc.i4.m1
L_0019: stfld int32 testdiedai.Program/<Power>d__0::<>1__state
L_001e: ldarg.0
L_001f: ldc.i4.1
L_0020: stfld int32 testdiedai.Program/<Power>d__0::<result>5__1
L_0025: ldarg.0
L_0026: ldc.i4.1
L_0027: stfld int32 testdiedai.Program/<Power>d__0::<counter>5__2
L_002c: br.s L_0070
L_002e: ldarg.0
L_002f: ldarg.0
L_0030: ldfld int32 testdiedai.Program/<Power>d__0::<result>5__1
L_0035: ldarg.0
L_0036: ldfld int32 testdiedai.Program/<Power>d__0::baseNumber
L_003b: mul
L_003c: stfld int32 testdiedai.Program/<Power>d__0::<result>5__1
L_0041: ldarg.0
L_0042: ldarg.0
L_0043: ldfld int32 testdiedai.Program/<Power>d__0::<result>5__1
L_0048: box int32
L_004d: stfld object testdiedai.Program/<Power>d__0::<>2__current
L_0052: ldarg.0
L_0053: ldc.i4.1
L_0054: stfld int32 testdiedai.Program/<Power>d__0::<>1__state
L_0059: ldc.i4.1
L_005a: ret
L_005b: ldarg.0
L_005c: ldc.i4.m1
L_005d: stfld int32 testdiedai.Program/<Power>d__0::<>1__state
L_0062: ldarg.0
L_0063: dup
L_0064: ldfld int32 testdiedai.Program/<Power>d__0::<counter>5__2
L_0069: ldc.i4.1
L_006a: add
L_006b: stfld int32 testdiedai.Program/<Power>d__0::<counter>5__2
L_0070: ldarg.0
L_0071: ldfld int32 testdiedai.Program/<Power>d__0::<counter>5__2
L_0076: ldarg.0
L_0077: ldfld int32 testdiedai.Program/<Power>d__0::highExponent
L_007c: ble.s L_002e
L_007e: ldc.i4.0
L_007f: ret
}
private bool MoveNext()
{
.override [mscorlib]System.Collections.IEnumerator::MoveNext
.maxstack 2
.locals init (
[0] int32 result,
[1] int32 counter,
[2] int32 CS$0$0000)
L_0000: ldarg.0
L_0001: ldfld int32 testdiedai.Program/<PowerBreak>d__5::<>1__state
L_0006: stloc.2
L_0007: ldloc.2
L_0008: ldc.i4.0
L_0009: bne.un.s L_002c
L_000b: ldarg.0
L_000c: ldc.i4.m1
L_000d: stfld int32 testdiedai.Program/<PowerBreak>d__5::<>1__state
L_0012: ldc.i4.1
L_0013: stloc.0
L_0014: ldc.i4.1
L_0015: stloc.1
L_0016: br.s L_0023
L_0018: ldloc.0
L_0019: ldarg.0
L_001a: ldfld int32 testdiedai.Program/<PowerBreak>d__5::baseNumber
L_001f: mul
L_0020: stloc.0
L_0021: br.s L_002c
L_0023: ldloc.1
L_0024: ldarg.0
L_0025: ldfld int32 testdiedai.Program/<PowerBreak>d__5::highExponent
L_002a: ble.s L_0018
L_002c: ldc.i4.0
L_002d: ret}