专栏首页平凡少年利用反射实现DataTable 与 List<T> 转换

利用反射实现DataTable 与 List<T> 转换

今天上班不太忙,就想着总结一下反射、扩展方法、以及lambda表达式的用法,自己就写了个小DEMO记录一下,希望各位大牛们看到后觉得不对的地方请及时提出。这篇文章中我只说明我的用法,作为一个备忘,基本的语法我不讲解,对这些概念不熟悉的童鞋在博客园上搜素一下,呢那个找到很多相关的讲解,小弟就先抛砖引玉了。

另附链接一枚,如果你想知道c#1.0--c#4.0 主要基础知识汇总,请猛点下面链接,你还可以看到该片文章中提到的知识点。

猛点我

概述反射

  •  通过反射可以提供类型信息,从而使得我们开发人员在运行时能够利用这些信息构造和使用对象。 
  •  反射机制允许程序在执行过程中动态地添加各种功能。

详细见我的163博客.NET反射详解

扩展方法

引MSDN对扩展方法的定义: 扩展方法使你能够向现有类型“添加”方法(包括你自定义的类型和对象噢),而无需创建新的派生类型、重新编译或以其他方式修改原始类型。扩展方法是一种特殊的静态方法,但是可以像扩展类型上的实例方法一样进行调用。对于用C#编写的客户端代码,调用扩展方法与调用在类型中实际定义的方法之间没有明显的差异。

lambda表达式

引百度百科对Lambda的定义“Lambda 表达式”是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型。 所有 Lambda 表达式都使用 Lambda 运算符 =>,该运算符读为“goes to”。该 Lambda 运算符的左边是输入参数(如果有),右边包含表达式或语句块。

说了这么多,开始上代码。

方法一:扩展方法与反射实现 DataTable 转 List<T>

public static  List<T> ToList<T>(this DataTable dt) where T:class,new()
       {
           Type t=typeof(T);
           PropertyInfo[] propertys = t.GetProperties();
           List<T> lst = new List<T>();
           string typeName = string.Empty;

           foreach (DataRow dr in dt.Rows)
           {
               T entity = new T();
               foreach (PropertyInfo pi in propertys)
               {
                   typeName = pi.Name;
                   if (dt.Columns.Contains(typeName))
                   {
                       if (!pi.CanWrite) continue;
                       object value = dr[typeName];
                       if (value == DBNull.Value) continue;
                       if (pi.PropertyType == typeof(string))
                       {
                           pi.SetValue(entity,value.ToString(),null);
                       }
                       else if (pi.PropertyType == typeof(int) || pi.PropertyType == typeof(int?))
                       {
                           pi.SetValue(entity,int.Parse(value.ToString()), null);
                       }
                       else if (pi.PropertyType == typeof(DateTime?) || pi.PropertyType == typeof(DateTime))
                       {
                           pi.SetValue(entity, DateTime.Parse(value.ToString()), null);
                       }
                       else if (pi.PropertyType == typeof(float))
                       {
                           pi.SetValue(entity, float.Parse(value.ToString()), null);
                       }
                       else if (pi.PropertyType == typeof(double))
                       {
                           pi.SetValue(entity, double.Parse(value.ToString()), null);
                       }
                       else
                       {
                           pi.SetValue(entity,value, null);
                       }
                   }
               }
               lst.Add(entity);
           }
           return lst;
       }

方法一调用

(1)首先创建一个实体类

 public class People
    {
        public string Name { get; set; }
        public int Age{get;set;}
    }

(2)调用

DataTable dt = new DataTable();
        dt.Columns.Add("Name");
        dt.Columns.Add("Age");
        DataRow dr = dt.NewRow();
        dr[0] = "eric";
        dr[1] = 20;
        dt.Rows.Add(dr);
        dr = dt.NewRow();
        dr[0] = "eric1";
        dr[1] = 22;
        dt.Rows.Add(dr);

        List<People> p = dt.ToList<People>();

方法二:扩展方法与Action委托实现数组的遍历操作(ForEach)

public static void ForEach<T>(this IEnumerable<T> ien,Action<T> express)
       {
           foreach (var item in ien)
           {
               express(item);
           }
           
       }

方法二调用

 List<string> lst = new List<string>();
        var arr = new string[3] { "eric01", "eric02", "eric03" };
        arr.ForEach(it => lst.Add(it));//这里面可以做更复杂的处理
        Response.Write(lst[0]);

方法三:利用方法一和方法二实现List<t>转换DataTable

public static DataTable ToDataTable<T>(this IEnumerable<T> value) where T : class,new()
       {
           List<PropertyInfo> lstProperty = new List<PropertyInfo>();
           Type type=typeof(T);
           DataTable dt = new DataTable();
           type.GetProperties().ForEach(p =>  //ForEach扩展方法,这里使用Array.ForEach(type.GetProperties(),p=>{})也是一样
           {
               lstProperty.Add(p);
               if (p.PropertyType.IsGenericType)//是否为泛型,泛型获取不到具体的类型
               {
                   dt.Columns.Add(p.Name);
               }
               else
               {
                   dt.Columns.Add(p.Name,p.PropertyType);
               }
           });
           if (value != null)
           {
               foreach (var item in value)
               {
                   //创建一个DataRow实例
                   DataRow row = dt.NewRow();
                   lstProperty.ForEach(p =>
                   {
                       row[p.Name] = p.GetValue(item, null);
                   });
                   dt.Rows.Add(row);
               }
           }
           return dt;
       }

OK了 今天就到此为止了,睡觉喽。每天学习一点点,每天进步一点点。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Knockout简单用法

        在最近做的一个项目中,页面数据全部通过js ajax调用webapi接口获取,也就是说页面的数据全部使用javascript脚本填充,这就想到了使用一个...

    写代码的猿
  • 数据访问模式之Repository模式

    数据访问层无非就是对数据进行增删改查,其中增、删、改等我们可以抽象出来写一个公共的接口或抽象类来定义这些方法,并采用一个基类实现这些方法,这样该基类派生的子类都...

    写代码的猿
  • webAPI 自动生成帮助文档

    之前在项目中有用到webapi对外提供接口,发现在项目中有根据webapi的方法和注释自动生成帮助文档,还可以测试webapi方法,功能很是强大,现拿出来与大家...

    写代码的猿
  • Vivado模块化综合技术的应用场景

    模块化综合技术的最大优势在于实现了Vivado在模块层面对设计的综合进行相应地优化处理,使得综合的设置更能匹配设计的需求,从而提高综合的QoR。这里我们将介绍一...

    Lauren的FPGA
  • 数据结构:栈的顺序存储结构

    栈(stack)是限定在表尾进行插入和删除操作的线性表。我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom) ,栈又称为后进先出(Las...

    s1mba
  • 通俗易懂设计模式解析——迭代器模式

      今天我们一起看看行为模式中的迭代器模式,迭代是重复反馈过程的活动,其目的通常是为了接近并到达所需的目标或结果。在系统开发中简单说可以理解成遍历。这种模式用于...

    小世界的野孩子
  • 使用Raspberry构建蜜罐捕获BlueKeep攻击

    BlueKeep是一个软件安全漏洞,它影响使用旧版Microsoft Windows 操作系统的计算机 ; Windows 8和Windows 10不受...

    洛米唯熊
  • 看我如何基于Python;Facepp打造智能监控系统

    由于种种原因,最近想亲自做一个基于python&facepp打造的智能监控系统。 0x00:萌芽 1:暑假在家很无聊 想出去玩,找不到人。玩个lol(已卸载),...

    FB客服
  • Apache安装时错误解析

    老七Linux
  • 一些比较好的技术文章收录

    10步完全理解sql http://blog.jobbole.com/55086/

    luxixing

扫码关注云+社区

领取腾讯云代金券