IEnumerable<T> 接口和GetEnumerator 详解
IEnumerable<T> 接口
公开枚举数,该枚举数支持在指定类型的集合上进行简单迭代。
若要浏览此类型的.NET Framework 源代码,请参阅参考源。
命名空间: System.Collections.Generic
程序集: mscorlib(在 mscorlib.dll 中)
public interface IEnumerable<out T> : IEnumerable
类型参数
- out T
-
要枚举的对象的类型。
此类型参数是协变。即可以使用指定的类型或派生程度更高的类型。有关协变和逆变的详细信息,请参阅 泛型中的协变和逆变。
IEnumerable<T> 类型公开以下成员。
方法
名称 | 描述 | |
---|---|---|
![]() ![]() ![]() |
GetEnumerator | 返回一个循环访问集合的枚举器。 |
GetEnumerator 详解
返回一个循环访问集合的枚举器。
命名空间: System.Collections.Generic
程序集: mscorlib(mscorlib.dll 中)
语法
IEnumerator<T> GetEnumerator()
返回IEnumerator<T>提供了通过公开来循环访问集合的能力Current属性。读取集合中的数据,但不是能修改集合,您可以使用枚举器。
最初,枚举数位于集合中的第一个元素之前。在此位置上,Current是不确定的。因此,您必须调用MoveNext方法使枚举器前进到之前读取值的集合的第一个元素Current。
Current返回同一个对象,直到MoveNext作为再次调用MoveNext设置Current到下一个元素。
如果MoveNext越过集合,该枚举数的末尾将被定位在集合中的最后一个元素之后和MoveNext返回false。当枚举数位于此位置上,对后续调用MoveNext也会返回false。如果最后一次调用到MoveNext返回false,Current是不确定的。您不能设置Current再次为集合的第一个元素必须改为创建新的枚举器实例。
一个枚举器没有对集合的独占访问,因此,只要集合保持不变,枚举器保持有效。如果进行了更改到集合中,如添加、 修改,或删除元素),则枚举器将失效,并可能会收到意外的结果时。此外,对集合进行枚举不是线程安全过程。若要保证线程安全,您应枚举期间锁定集合,或实现同步对集合。
集合中的默认实现System.Collections.Generic命名空间时不同步。
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Linq; public class App
{
// Excercise the Iterator and show that it's more
// performant.
public static void Main()
{
TestStreamReaderEnumerable();
Console.WriteLine("---");
TestReadingFile();
} public static void TestStreamReaderEnumerable()
{
// Check the memory before the iterator is used.
long memoryBefore = GC.GetTotalMemory(true);
IEnumerable<String> stringsFound;
// Open a file with the StreamReaderEnumerable and check for a string.
try {
stringsFound =
from line in new StreamReaderEnumerable(@"c:\temp\tempFile.txt")
where line.Contains("string to search for")
select line;
Console.WriteLine("Found: " + stringsFound.Count());
}
catch (FileNotFoundException) {
Console.WriteLine(@"This example requires a file named C:\temp\tempFile.txt.");
return;
} // Check the memory after the iterator and output it to the console.
long memoryAfter = GC.GetTotalMemory(false);
Console.WriteLine("Memory Used With Iterator = \t"
+ string.Format(((memoryAfter - memoryBefore) / ).ToString(), "n") + "kb");
} public static void TestReadingFile()
{
long memoryBefore = GC.GetTotalMemory(true);
StreamReader sr;
try {
sr = File.OpenText("c:\\temp\\tempFile.txt");
}
catch (FileNotFoundException) {
Console.WriteLine(@"This example requires a file named C:\temp\tempFile.txt.");
return;
} // Add the file contents to a generic list of strings.
List<string> fileContents = new List<string>();
while (!sr.EndOfStream) {
fileContents.Add(sr.ReadLine());
} // Check for the string.
var stringsFound =
from line in fileContents
where line.Contains("string to search for")
select line; sr.Close();
Console.WriteLine("Found: " + stringsFound.Count()); // Check the memory after when the iterator is not used, and output it to the console.
long memoryAfter = GC.GetTotalMemory(false);
Console.WriteLine("Memory Used Without Iterator = \t" +
string.Format(((memoryAfter - memoryBefore) / ).ToString(), "n") + "kb");
}
} // A custom class that implements IEnumerable(T). When you implement IEnumerable(T),
// you must also implement IEnumerable and IEnumerator(T).
public class StreamReaderEnumerable : IEnumerable<string>
{
private string _filePath;
public StreamReaderEnumerable(string filePath)
{
_filePath = filePath;
} // Must implement GetEnumerator, which returns a new StreamReaderEnumerator.
public IEnumerator<string> GetEnumerator()
{
return new StreamReaderEnumerator(_filePath);
} // Must also implement IEnumerable.GetEnumerator, but implement as a private method.
private IEnumerator GetEnumerator1()
{
return this.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator1();
}
} // When you implement IEnumerable(T), you must also implement IEnumerator(T),
// which will walk through the contents of the file one line at a time.
// Implementing IEnumerator(T) requires that you implement IEnumerator and IDisposable.
public class StreamReaderEnumerator : IEnumerator<string>
{
private StreamReader _sr;
public StreamReaderEnumerator(string filePath)
{
_sr = new StreamReader(filePath);
} private string _current;
// Implement the IEnumerator(T).Current publicly, but implement
// IEnumerator.Current, which is also required, privately.
public string Current
{ get
{
if (_sr == null || _current == null)
{
throw new InvalidOperationException();
} return _current;
}
} private object Current1
{ get { return this.Current; }
} object IEnumerator.Current
{
get { return Current1; }
} // Implement MoveNext and Reset, which are required by IEnumerator.
public bool MoveNext()
{
_current = _sr.ReadLine();
if (_current == null)
return false;
return true;
} public void Reset()
{
_sr.DiscardBufferedData();
_sr.BaseStream.Seek(, SeekOrigin.Begin);
_current = null;
} // Implement IDisposable, which is also implemented by IEnumerator(T).
private bool disposedValue = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
} protected virtual void Dispose(bool disposing)
{
if (!this.disposedValue)
{
if (disposing)
{
// Dispose of managed resources.
}
_current = null;
if (_sr != null) {
_sr.Close();
_sr.Dispose();
}
} this.disposedValue = true;
} ~StreamReaderEnumerator()
{
Dispose(false);
}
}
// This example displays output similar to the following:
// Found: 2
// Memory Used With Iterator = 33kb
// ---
// Found: 2
// Memory Used Without Iterator = 206kb
IEnumerable<T> 接口和GetEnumerator 详解的更多相关文章
- c# WebApi之接口返回类型详解
c# WebApi之接口返回类型详解 https://blog.csdn.net/lwpoor123/article/details/78644998
- “全栈2019”Java第六十四章:接口与静态方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- “全栈2019”Java第六十三章:接口与抽象方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- “全栈2019”Java第六十二章:接口与常量详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- LWIP network interface 即 LWIP 的 硬件 数据 接口 移植 首先 详解 STM32 以太网数据 到达 的第一站: ETH DMA 中断函数
要 运行 LWIP 不光 要实现 OS 的 一些 接口 ,还要 有 硬件 数据 接口 移植 ,即 网线上 来的 数据 怎么个形式 传递给 LWIP ,去解析 做出相应的 应答 ,2017 ...
- 抽象类和接口的区别详解、package和import
1.抽象类和接口以及抽象类和接口的区别. 1.1.抽象类的基础语法(见昨天笔记) 1.2.接口的基础语法 1.接口是一种"引用数据类型". 2.接口是完全抽象的. 3.接口怎么定义 ...
- Java接口修饰符详解
接口就是提供一种统一的”协议”,而接口中的属性也属于“协议”中的成员.它们是公共的,静态的,最终的常量.相当于全局常量.抽象类是不“完全”的类,相当于是接口和具体类的一个中间层.即满足接口的抽象,也满 ...
- python接口自动化(三)--如何设计接口测试用例(详解)
简介 上篇我们已经介绍了什么是接口测试和接口测试的意义.在开始接口测试之前,我们来想一下,如何进行接口测试的准备工作.或者说,接口测试的流程是什么?有些人就很好奇,接口测试要流程干嘛?不就是拿着接口文 ...
- Spring钩子方法和钩子接口的使用详解
本文转自:http://www.sohu.com/a/166804449_714863 前言 SpringFramework其实具有很高的扩展性,只是很少人喜欢挖掘那些扩展点,而且官方的Refrenc ...
随机推荐
- 沈阳网络赛F-Fantastic Graph【贪心】or【网络流】
"Oh, There is a bipartite graph.""Make it Fantastic." X wants to check whether a ...
- c# 调用声音文件
一.使用C#自带的SoundPlayer using System.Media; SoundPlayer sound = new SoundPlayer("声音.wav"); so ...
- Python开发【模块】:matplotlib 绘制折线图
matplotlib 1.安装matplotlib ① linux系统安装 # 安装matplotlib模块 $ sudo apt-get install python3-matplotlib # 如 ...
- 12.GIT多人协作
当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin. 查看远程库的信息 $ git remote origin $ ...
- ssh 配置文件讲解大全 ssh调试模式 sftp scp strace进行调试 特权分离
ssh 配置文件讲解大全 ssh调试模式 sftp scp strace进行调试 特权分离 http://blog.chinaunix.net/uid-16728139-id-3265394.h ...
- OOP理解
https://www.cnblogs.com/xiaosongluffy/p/5072501.html OOP是面向对象编程,有几大基础特性.抽象,封装,继承,多态 1:抽象:将世界上的具体事物提取 ...
- Hyperledger Fabric 开发环境搭建 centos7系统
一.安装GO语言 下载最新版的go 打开Terminal,输入命令(以下命令都是以root管理员的角色进行的) su 输入密码:***** wget https://storage.googleapi ...
- Android 压力测试工具Monkey
原文地址http://www.syhm52.com/tools/17.html 一.Monkey定义探索软件测试工具有哪些,本文主要介绍Monkey工具.Monkey测试是Android平台自动化测试 ...
- C#之父
来自为知笔记(Wiz)
- (16)Cocos2d-x 多分辨率适配完全解析
Overview 从Cocos2d-x 2.0.4开始,Cocos2d-x提出了自己的多分辨率支持方案,废弃了之前的retina相关设置接口,提出了design resolution概念. 3.0中有 ...