千家信息网

C#迭代器局部变量是什么

发表于:2024-11-28 作者:千家信息网编辑
千家信息网最后更新 2024年11月28日,这篇文章主要介绍了C#迭代器局部变量是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。看看***的测试,是不是不管具体的集合如何改变
千家信息网最后更新 2024年11月28日C#迭代器局部变量是什么

这篇文章主要介绍了C#迭代器局部变量是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

看看***的测试,是不是不管具体的集合如何改变,遍历代码都非常稳定?而且扩展新的集合类也非常方便,只是添加代码不会修改原来的代码,符合开闭原则。当然,这么好的解决方案微软当然不会放过,现在C# 2.0里已经内置了对C#迭代器的支持,看看System.Collections, System.Collections.Generic命名空间,所有的集合都实现了这个接口:IEnumerable,这个接口还有泛型的版本。注意到这个接口只有一个方法:IEnumerator GetEnumerator();,IEnumerator就是C#迭代器的接口,相当于我的实例里面的Iterator,它也有泛型的版本。

那么现在在.net里所有的集合类都可以这样访问了:

IEnumerator ienumerator = list.GetEnumerator();  while(ienumerator.MoveNext())  {  object current = ienumerator.Current;  }

但是这样访问也太麻烦了,所以C#里出现了foreach关键字,我们来看看foreach背后发生了什么

public static void Main()  {  ArrayList list = new ArrayList();  list.Add(1);  list.Add(2);  list.Add(3);  foreach (object item in list)  {  Console.WriteLine(item.ToString());  }  }

下面是它对应的IL代码:

.method private hidebysig static void Main() cil managed  {  .entrypoint  .maxstack 2  .locals init (  [0] class [mscorlib]System.Collections.ArrayList list,  [1] object item,  [2] class [mscorlib]System.Collections.IEnumerator CS$5$0000,  [3] class [mscorlib]System.IDisposable CS$0$0001)  L_0000: newobj instance void [mscorlib]System.Collections.ArrayList::.ctor()  L_0005: stloc.0   L_0006: ldloc.0   L_0007: ldc.i4.1   L_0008: box int32  L_000d: callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object)  L_0012: pop   L_0013: ldloc.0   L_0014: ldc.i4.2   L_0015: box int32  L_001a: callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object)  L_001f: pop   L_0020: ldloc.0   L_0021: ldc.i4.3   L_0022: box int32  L_0027: callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object)  L_002c: pop   L_002d: ldloc.0   L_002e: callvirt instance class [mscorlib]System.Collections.IEnumerator [mscorlib]System.Collections.ArrayList::GetEnumerator()  L_0033: stloc.2   L_0034: br.s L_0048  L_0036: ldloc.2   L_0037: callvirt instance object [mscorlib]System.Collections.IEnumerator::get_Current()  L_003c: stloc.1   L_003d: ldloc.1   L_003e: callvirt instance string [mscorlib]System.Object::ToString()  L_0043: call void [mscorlib]System.Console::WriteLine(string)  L_0048: ldloc.2   L_0049: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()  L_004e: brtrue.s L_0036  L_0050: leave.s L_0063  L_0052: ldloc.2   L_0053: isinst [mscorlib]System.IDisposable  L_0058: stloc.3   L_0059: ldloc.3   L_005a: brfalse.s L_0062  L_005c: ldloc.3   L_005d: callvirt instance void [mscorlib]System.IDisposable::Dispose()  L_0062: endfinally   L_0063: call string [mscorlib]System.Console::ReadLine()  L_0068: pop   L_0069: ret   .try L_0034 to L_0052 finally handler L_0052 to L_0063  }

从.locals init 那里可以看出编译器为我们添加了两个C#迭代器局部变量,一个就是C#迭代器。

L_002d: ldloc.0   L_002e: callvirt instance class [mscorlib]System.Collections.IEnumerator [mscorlib]System.Collections.ArrayList::GetEnumerator()  L_0033: stloc.2

这三行代码告诉我们,调用list的GetEnumerator()方法,获取C#迭代器实例将其赋值给编译器为我们添加的那个C#迭代器局部变量,接着是L_0034: br.s L_0048,br.s这个指令是强制跳转,我们接着看

L_0048: ldloc.2   L_0049: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()

感谢你能够认真阅读完这篇文章,希望小编分享的"C#迭代器局部变量是什么"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!

0