相信大家在学习c#的时候,经常会看到IEnumerable、IEnumerator这样的接口或返回类型,在写代码时经常会对数组或List集合进行遍历。那IEnumerable和IEnumerator是干什么的呢?有什么区别?数组和List集合为什么可以遍历而其他某些类型或对象不能遍历?它们之间有什么联系呢?

  针对这么多疑问,我本来是想来写一篇文章来记录下的,但我在网上又发现了一篇写的很好的文章,对它们之间的关系讲的很详细,我觉得就算我写的话,不见得写的比这篇文章好 :-)。以下是文章链接 http://blog.csdn.net/byondocean/article/details/6871881 推荐看,不然会影响对后面代码的理解,(老鸟忽略)当然了,这些都不是本文的重点,就如文章的标题,我想写的是 ”由IEnumerable和IEnumerator的延伸“,。。。好吧,我们正式进入主题。

  比如我们在开发某个功能时,页面查询的数据量比较大,并且关联的表也很多, 这个时候写sql语句无疑是首选,但我们为了便于操作,还要把DataTable遍历转换成List,当然你会说,一般ORM框架不是支持原生的SQL语句吗?比如EF的SqlQuery,它直接就返回了可枚举的对象了。是的,但OMR框架再怎么封装,最终也是通过ADO.NET方式访问数据库的。

我们通过查询得到了一个DataTable数据集合,这个时候我们让它返回List,我们希望的调用方式如下:

  1. var data = oh.excuteQuery(strSql).FillObjects<Person>().ToList();

  传入一个Person 返回 List<Person >非常简洁的调用,像Linq to objects 般流畅,接下来我们就来实现它吧。

  1. public static class DataTableConvertToList
  2. {
  3.   //使用静态方法扩展datatable
  4. public static IEnumerable<T> FillObjects<T>(this DataTable dataTable) where T : class
  5. {
  6. return new DataTableEnumerable<T>() { Data = dataTable };
  7. }
  8. }
  1. public class DataTableEnumerable<T> : IEnumerable<T>
  2. {
  3. public DataTable Data;
  4.  
  5. public IEnumerator<T> GetEnumerator()
  6. {
  7. return new DataTableEnumerator<T>(Data);
  8. }
  9.  
  10. System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
  11. {
  12. return new DataTableEnumerator<T>(Data);
  13. }
  14.  
  15.    }
  1. public class DataTableEnumerator<T> : IEnumerator<T>
  2. {
  3. private DataTable data;
  4. private int index = -;
  5.  
  6. public DataTableEnumerator(DataTable data)
  7. {
  8. if (data == null)
  9. {
  10. data = new DataTable();
  11. }
  12. this.data = data;
  13. }
  14.  
  15. public T Current
  16. {
  17. get { return convert(); }
  18. }
  19.  
  20. public void Dispose() { }
  21.  
  22. object System.Collections.IEnumerator.Current
  23. {
  24. get { return convert(); }
  25. }
  26.  
  27. public bool MoveNext()
  28. {
  29. index++;
  30. return index < data.Rows.Count;
  31. }
  32.  
  33. public void Reset()
  34. {
  35. index = -;
  36. }
  37.  
  38. private T convert()
  39. {
  40. var row = data.Rows[index];
  41.  
  42. var tType = typeof(T);
  43.  
  44. var properties = tType.GetProperties();
  45.  
  46.   //反射动态调用这个类
  47. var obj = tType.GetConstructor(new Type[] { }).Invoke(null);
  48.  
  49. foreach (DataColumn col in data.Columns)
  50. {
  51. var val = row[col];
  52. if (val.GetType() == typeof(DBNull))
  53. {
  54. continue;
  55. }
  56. var prop = properties.SingleOrDefault(m => m.Name.ToUpper() == col.ColumnName.ToUpper());
  57. if (prop == null)
  58. {
  59. continue;
  60. }
  61. if (prop.PropertyType.IsGenericType && prop.PropertyType.Name == typeof(Nullable<>).Name)
  62. {
  63. prop.SetValue(obj,Convert.ChangeType(val, prop.PropertyType.GetGenericArguments()[]), null);
  64. }
  65. else
  66. {
  67.   
  68. prop.SetValue(obj, Convert.ChangeType(val, prop.PropertyType), null);
  69. }
  70. }
  71.  
  72. return (T)obj;
  73. }
  74.    }
  75.   

  最后我们来看下效果:

  上面总的框架是通过继承IEnumerable和IEnumerator 接口来实现迭代的,最后的绑定是通过反射实现的。

由IEnumerable和IEnumerator的延伸的更多相关文章

  1. C# ~ 从 IEnumerable / IEnumerator 到 IEnumerable<T> / IEnumerator<T> 到 yield

    IEnumerable / IEnumerator 首先,IEnumerable / IEnumerator 接口定义如下: public interface IEnumerable /// 可枚举接 ...

  2. 细说 C# 中的 IEnumerable和IEnumerator接口

    我们先思考几个问题: 为什么在foreach中不能修改item的值? 要实现foreach需要满足什么条件? 为什么Linq to Object中要返回IEnumerable? 接下来,先开始我们的正 ...

  3. 迭代器学习之一:使用IEnumerable和IEnumerator接口

    写博客是检验我学习的成果之一以及自我总结的一种方式,以后会经常利用这种方式进行技术交流和自我总结,其中认识不深难免会有错误,但是一直懂得不懂就问,不懂就学的道理! 1.首先看一个简单的列子 , , , ...

  4. IEnumerable和IEnumerator

    概述 IEnumerable和IEnumerator接口存在的意义:用来实现迭代的功能! public interface IEnumerable { IEnumerator GetEnumerato ...

  5. 关于迭代器中IEnumerable与IEnumerator的区别

    首先是IEnumerable与IEnumerator的定义: 1.IEnumerable接口允许使用foreach循环,包含GetEnumerator()方法,可以迭代集合中的项. 2.IEnumer ...

  6. IEnumerable和IEnumerator 详解 (转)

    原文链接:http://blog.csdn.net/byondocean/article/details/6871881 参考链接:http://www.cnblogs.com/hsapphire/a ...

  7. C#基础知识系列九(对IEnumerable和IEnumerator接口的糊涂认识)

    前言 IEnumerable.IEnumerator到现在为止对这两个接口还是不太理解,不理解但是自己总是想着试着要搞明白,毕竟自己用的少,所以在此先记录一下.以备自己日后可以来翻查,同时也希望园子里 ...

  8. [转]那些年我还不懂:IList,ICollection,IEnumerable,IEnumerator,IQueryable

    1.首先看一个简单的例子 int[] myArray = { 1, 32, 43, 343 }; IEnumerator myie = myArray.GetEnumerator(); myie.Re ...

  9. 转载IEnumerable与IEnumerator区别

    public interface IEnumerable {     IEnumerator GetEnumerator(); }   public interface IEnumerator {   ...

随机推荐

  1. 破解Kaleidoscope-2.1.0-134,无限试用

    找到超时时间计算的地方,有非常多处,大概几十外,大约类似下面的代码,作者应该是copy了非常多份反复的代码, 10000C592 F2 0F 10 8D 40 FE FF FF             ...

  2. CSS3+HTML5特效7 - 特殊的 Loading 效果

    效果如下     实现原理: 利用CSS3的@keyframes规则创建动画效果: 使用CSS3的animation效果完成滚动切换. 代码说明: 样式表中@-webkit-keyframes及@ke ...

  3. php exit、return、break、continue之间的差别,具体介绍

    相信大家在php开发中有几个经常使用的停止程序和循环的keyword的误区( exit.return.break.continue) exit 退出全部脚本,是个函数 return 语言结构的使用方法 ...

  4. 分享一个解析XML成为php数组的方法

    原文:分享一个解析XML成为php数组的方法 <?php /* * To change this template, choose Tools | Templates * and open th ...

  5. 瘸腿蛤蟆笔记29-cocos2d-x-3.2 Box2d物理引擎dynamics模块介绍

    转载标明出处:http://blog.csdn.net/notbaron/article/details/38611335 上篇回想 本篇名言:奋斗.寻觅.发现,而不屈服.[诗人丁尼生] 上篇中,我们 ...

  6. 接口自动化测试:Thrift框架RPC协议客户端开发

    import java.lang.Thread.State;import java.util.Iterator;import java.util.List; import org.apache.thr ...

  7. asp.net中TextBox里面实现回车触发指定事件

    原文:asp.net中TextBox里面实现回车触发指定事件 我在一个user_top用户控件里面做了个包括搜索的功能.然后再一个页面中添加这个用户控件.浏览时候在textbox里面输入搜索内容后.下 ...

  8. CSS中选择器优先级顺序实战讲解

    原文:CSS中选择器优先级顺序实战讲解 我们有些程序猿在给一个元素(比如div)应用样式的时候,会有一些疑问,为什么我写在后面的样式不能覆盖前面的样式呢,不是说CSS是层叠样式表吗? 如果你在开发中也 ...

  9. 终于有人把O2O、C2C、B2B、B2C的区别讲透了!

    终于有人把O2O.C2C.B2B.B2C的区别讲透了! 一.O2O.C2C.B2B.B2C的区别在哪里? O2O是online to offline分为四种运营模式: 1.online to offl ...

  10. 【原版的:参赛作品】窥秘懒---android打开下拉手势刷新时代

    小飒的成长史原创作品:窥视懒人的秘密---android下拉刷新开启手势的新纪元转载请注明出处 **************************************************** ...