大家好,欢迎来到IT知识分享网。
IEnumerable 和 IEnumerator
IEnumerator接口定义了以向前方式遍历集合的基本底层协议。
声明如下:
public interface IEnumerator { bool MoveNext(); object Current { get; } void Reset(); }
- MoveNext将当前元素向前移动到下一个位置,如果集合没有更多元素,那么它会返回false。
- Current返回当前位置元素。在取得第一个元素之前 必须先调用MoveNext,即使空集合也支持该操作。
- Reset作用就是当前位置移回起点,并允许再一次枚举集合。此方法一般并不建议使用,因为完全可以重新实例化一个枚举器。
通常,集合本身并不实现枚举器,而是通过IEnumerable接口提供枚举器:
public interface IEnumerable { IEnumerator GetEnumerator(); }
通过GetEnumerator返回枚举器,可以灵活地将迭代逻辑转移到另一个类上。此外,多个消费者可以同时枚举同一个集合而不互相影响。IEnumerable可以看作IEnumerator的提供者,它是所有集合类需要实现的最基础接口。
下面示例了基本用法:
string s = "Hello"; IEnumerator rator = s.GetEnumerator(); while (rator.MoveNext()) { char c = (char)rator.Current; Console.Write(c + "."); }
然而,我们很少采用这种方式直接调用枚举器的方法,因为C#提供了更快捷的语法:foreach语句。
foreach (char c in s) { Console.Write(c + "."); }
IEnumerable<T> 和 IEnumerator<T>
IEnumerable 和 IEnumerator 总是和它们的泛型版本同时实现:
public interface IEnumerator<T> : IEnumerator, IDisposable { T Current { get; } } public interface IEnumerable<T> : IEnumerable { IEnumerator<T> GetEnumerator(); }
这些接口通过定义一个类型化的Current和GetEnumerator强化了静态类型安全性,避免了值类型元素装箱的额外开销,更加方便了。
集合类的标准做法是公开提供IEnumerable<T>接口,并通过显式接口实现,而“隐藏”非泛型的IEnumerable接口。如果直接调用GetEnumerator(),则返回类型安全的泛型IEnumerator<T>。但是有时候这个规则也会由于向后兼容性而破坏,比如数组就必须返回非泛型的以避免破坏之前C#版本代码。
IEnumerator<T>也同时继承了IDisposable,这样枚举器就可以在枚举结束后确保释放这些资源。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/159713.html