C#迭代器局部变量

开发 后端
这里介绍C#迭代器局部变量,IEnumerator就是C#迭代器的接口,相当于我的实例里面的Iterator,它也有泛型的版本。

C#迭代器还是比较常见的东西,这里我们主要介绍C#迭代器局部变量,包括介绍C#里出现了foreach关键字等方面。

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

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

  1. IEnumerator ienumerator = list.GetEnumerator();  
  2. while(ienumerator.MoveNext())  
  3. {  
  4. object current = ienumerator.Current;  

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

  1. public static void Main()  
  2. {  
  3. ArrayList list = new ArrayList();  
  4. list.Add(1);  
  5. list.Add(2);  
  6. list.Add(3);  
  7. foreach (object item in list)  
  8. {  
  9. Console.WriteLine(item.ToString());  
  10. }  
  11. }  

下面是它对应的IL代码:

  1. .method private hidebysig static void Main() cil managed  
  2. {  
  3. .entrypoint  
  4. .maxstack 2  
  5. .locals init (  
  6. [0] class [mscorlib]System.Collections.ArrayList list,  
  7. [1] object item,  
  8. [2] class [mscorlib]System.Collections.IEnumerator CS$5$0000,  
  9. [3] class [mscorlib]System.IDisposable CS$0$0001)  
  10. L_0000: newobj instance void [mscorlib]System.Collections.ArrayList::.ctor()  
  11. L_0005: stloc.0   
  12. L_0006: ldloc.0   
  13. L_0007: ldc.i4.1   
  14. L_0008: box int32  
  15. L_000d: callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object)  
  16. L_0012: pop   
  17. L_0013: ldloc.0   
  18. L_0014: ldc.i4.2   
  19. L_0015: box int32  
  20. L_001a: callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object)  
  21. L_001f: pop   
  22. L_0020: ldloc.0   
  23. L_0021: ldc.i4.3   
  24. L_0022: box int32  
  25. L_0027: callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object)  
  26. L_002c: pop   
  27. L_002d: ldloc.0   
  28. L_002e: callvirt instance class [mscorlib]System.Collections.IEnumerator [mscorlib]
  29. System.Collections.ArrayList::GetEnumerator()  
  30. L_0033: stloc.2   
  31. L_0034: br.s L_0048  
  32. L_0036: ldloc.2   
  33. L_0037: callvirt instance object [mscorlib]System.Collections.IEnumerator::get_Current()  
  34. L_003c: stloc.1   
  35. L_003d: ldloc.1   
  36. L_003e: callvirt instance string [mscorlib]System.Object::ToString()  
  37. L_0043: call void [mscorlib]System.Console::WriteLine(string)  
  38. L_0048: ldloc.2   
  39. L_0049: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()  
  40. L_004e: brtrue.s L_0036  
  41. L_0050: leave.s L_0063  
  42. L_0052: ldloc.2   
  43. L_0053: isinst [mscorlib]System.IDisposable  
  44. L_0058: stloc.3   
  45. L_0059: ldloc.3   
  46. L_005a: brfalse.s L_0062  
  47. L_005c: ldloc.3   
  48. L_005d: callvirt instance void [mscorlib]System.IDisposable::Dispose()  
  49. L_0062: endfinally   
  50. L_0063: call string [mscorlib]System.Console::ReadLine()  
  51. L_0068: pop   
  52. L_0069: ret   
  53. .try L_0034 to L_0052 finally handler L_0052 to L_0063  

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

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

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

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

【编辑推荐】

  1. C# lock关键字叙述
  2. C#.Net FrameWork简介
  3. C# new和override简单描述
  4. C#值类型和引用类型浅谈
  5. C#标识符简单分析
责任编辑:佚名 来源: IT168
相关推荐

2009-08-27 10:08:36

C#隐含类型局部变量

2009-08-26 15:39:08

C#隐式类型局部变量

2009-09-17 13:05:38

Linq局部变量类型

2009-08-26 16:26:37

C#迭代器模式

2009-08-11 13:59:41

迭代器模式C# Iterator

2009-08-19 15:18:53

迭代器

2018-05-14 09:15:24

Python变量函数

2009-09-11 10:07:05

Linq隐式类型化局部

2009-10-12 14:13:00

VB.NET使用局部变

2009-12-15 10:48:54

Ruby局部变量

2020-11-11 21:26:48

函数变量

2024-05-29 08:49:22

Python全局变量局部变量

2015-01-07 14:41:32

Android全局变量局部变量

2021-09-28 07:12:09

函数内存

2010-03-15 09:32:56

Python函数

2017-02-08 12:28:37

Android变量总结

2009-09-22 17:21:24

线程局部变量

2023-09-24 23:40:54

Python变量

2009-08-18 17:17:05

C#局部类型

2010-10-14 09:34:34

JVM局部变量
点赞
收藏

51CTO技术栈公众号