如何重复使用IEnumerable对象来枚举?
2014-11-30 18:46
232 查看
我在2011年9月发表了一个问问,http://q.cnblogs.com/q/28679/。
没人理我。
自己看了一下,尝试自己解决:
为什么泛型集合没有Reset的实现?我认为是有些数据源回到首个元素比较浪费性能,甚至不可能,比如网络流。
枚举变量要求源不可以变,因为枚举变量是一个位置信息,源结构发生变化,增加或者减少,位置信息很可能变得没有意义,但不是一定。
观察一下枚举器的一般实现(yield生成代码),首先是在数据源里面产生一个内部类(枚举器),当foreach 调用数据源的GetEnumerator(), new 这个内部类的实例,该实例就保存了当前数据源中位置信息。其他自定义的数据源也是类似的原理。
当源发生变化,位置信息没有义务要发生相应的变化,这不是设计规范,大部分实现可以做到,但是也不排除特殊情况,而数据源的设计是一个高度适用的方案,因此无法保证修改后位置信息还是有效的。
第二个问题是,如何重复使用枚举器。枚举器是一个不断MoveNext的位置变量,不能往回走,提出这个问题本身就不是一个好的问题。为何当初我会提出,主要是我没有理解枚举器的实现机制,没有将linQ语句和产生枚举器这点区分开来,我以为书写一个复杂的linQ语句,产生一个枚举器之后,这个语句又要重新书写。那是因为没有理解foreach 调用了数据源的GetEnumerator()函数,这个函数创建了一个全新的枚举器,也就是根本可以直接使用这个数据源,重用这段linQ语句,foreach会产生全新的枚举器,不需要我担心。
没人理我。
自己看了一下,尝试自己解决:
原问题: |
MSDN: 在非泛型集合中,您可以在调用 Reset 后调用 MoveNext,将枚举数移回集合的开始处。 在泛型集合中,您不能再将 Current 设置为集合的第一个元素;而须创建新的枚举数实例。 ------------------------ 一个复杂的Linq 变量停难定义的,有时候要重复使用几次,但是MSDN里面说要重新创建,难道又要书写一次linq代码么?或者产生拷贝就可以? 请给出重复使用该枚举变量的解决方案。 另外: MSDN: 只要该集合保持不变,枚举数也就保持有效。如果对该集合进行了更改(例如添加、修改或删除了元素),该枚举数将失效(这一变化是不可逆转的),且其行为将变为未定义。 -------------------------------- 假设我定义了一个枚举数,但是还没使用,然后数据源发生变化,我这个枚举数就没有用了么? |
枚举变量要求源不可以变,因为枚举变量是一个位置信息,源结构发生变化,增加或者减少,位置信息很可能变得没有意义,但不是一定。
观察一下枚举器的一般实现(yield生成代码),首先是在数据源里面产生一个内部类(枚举器),当foreach 调用数据源的GetEnumerator(), new 这个内部类的实例,该实例就保存了当前数据源中位置信息。其他自定义的数据源也是类似的原理。
当源发生变化,位置信息没有义务要发生相应的变化,这不是设计规范,大部分实现可以做到,但是也不排除特殊情况,而数据源的设计是一个高度适用的方案,因此无法保证修改后位置信息还是有效的。
第二个问题是,如何重复使用枚举器。枚举器是一个不断MoveNext的位置变量,不能往回走,提出这个问题本身就不是一个好的问题。为何当初我会提出,主要是我没有理解枚举器的实现机制,没有将linQ语句和产生枚举器这点区分开来,我以为书写一个复杂的linQ语句,产生一个枚举器之后,这个语句又要重新书写。那是因为没有理解foreach 调用了数据源的GetEnumerator()函数,这个函数创建了一个全新的枚举器,也就是根本可以直接使用这个数据源,重用这段linQ语句,foreach会产生全新的枚举器,不需要我担心。
相关文章推荐
- 如何使用 ADO Stream 对象访问和修改 SQL Server BLOB 数据
- 如何使用 Forms 身份验证创建 GenericPrincipal 对象
- 如何使用动态共享对象的模式来安装PHP
- 关于.NET程序中使用Excel对象后,如何结束残留的Excel进程。
- 《LoadRunner没有告诉你的》之七——使用 LoadRunner 连续长时间执行测试,如何保证参数化的数据足够又不会重复?
- 在C++ Builder中如何通过对象名称来访问到该对象呢?答案就是使用MAP容器。
- ABAP--如何创建和使用sap的号码范围对象
- VIsual Basic 2005 - 如何使用 SqlBulkCopy 对象来执行大量复制作业
- VIsual Basic 2005 - 如何使用 SqlBulkCopy 对象来执行大量复制作业
- 如何使用 WMI 枚举当前系统进程?
- 用javascript操作xml-->Web设计中如何使用XML数据源对象(转载)
- 如何使用 Visual C# .NET 从 DataSet 对象更新数据库
- 如何查找和使用 Office 对象模型文档
- 如何使用动态共享对象的模式来安装PHP
- 如何设计和使用自定义的权限对象(自定义权限检查函数)
- Web设计中如何使用XML数据源对象
- 如何设计和使用自定义的权限对象(自定义权限检查函数)
- 如何在 Internet Explorer 中禁用和使用 ADODB.Stream 对象
- 下面的示例演示如何使用传递到事件处理方法的 GridViewCommandEventArgs 对象确定引发事件的按钮的命令名。
- 如何使用反射取得对象的属性值