C#中的反射和扩展方法的运用
前段时间做了一个练手的小项目,采用的是三层架构,也就是Models,IDAL,DAL,BLL 和 Web , 在DAL层中各个类中有一个方法比较常用,那就是 RowToClass ,顾名思义,也就是将 DataTable 中的数据封装到 Models 中。结果导致在DAL各个类中写了很多类似的方法,后来就直接把它抽取出来做成了 DataTable和 DataRow的扩展方法,
下面是代码:
using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection; namespace DAL
{
/// <summary>
/// 用于给 DataTable和 DataRow扩展方法
/// </summary>
public static class TableExtensionMethod
{ /// <summary>
/// 功能:
/// 给DataTable扩展了一个方法,能够将DataTable中的行转变为对应的class对象,并封装到List集合中;
/// </summary>
/// <typeparam name="T">需要转变成为的class类型</typeparam>
/// <param name="table">传入的DataTable对象</param>
/// <returns>返回一个封装了对应class的List集合</returns>
public static List<T> TableToClass<T>(this DataTable table)
{
Type type = typeof(T);
PropertyInfo[] propArr = type.GetProperties();//获取所有属性
List<T> list = new List<T>();
DataRowCollection rows = table.Rows;
int len = rows[0].ItemArray.Length;//获取第一行的列数,即class的属性个数
for (int i = 0; i < rows.Count; i++)
{
T t = (T)Activator.CreateInstance(type);
for (int j = 0; j < len; j++)//这里之所以不使用propArr.Length,是因为有些Models的属性在数据表中不存在对应的列
{
propArr[j].SetValue(t, rows[i][j]);
}
list.Add(t);
t = default(T);
}
return list;
} /// <summary>
/// 功能:
/// DataRow的扩展方法;
/// 能够将DataRow对象封装到泛型对象中
/// </summary>
/// <typeparam name="T">需要转换成为的class类型</typeparam>
/// <param name="row">被转换的行</param>
/// <returns>封装了行数据的class对象</returns>
public static T RowToClass<T>(this DataRow row)
{
//Type type = Assembly.Load(classFullName).GetType();
Type type = typeof(T);
T t = (T)Activator.CreateInstance(type);
PropertyInfo[] propArr = type.GetProperties();
int len = row.ItemArray.Length;
for (int i = 0; i < len; i++)
{
propArr[i].SetValue(t, row[i]);
}
return t;
} /// <summary>
/// 功能:
/// DataRowCollection的扩展方法;
/// 能够将DataRowCollection对象封装到泛型List集合中
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="rows"></param>
/// <returns></returns>
public static List<T> RowToClass<T>(this DataRow row, DataRow[] rowArr)
{
Type type = typeof(T);
PropertyInfo[] propArr = type.GetProperties();
int len = rowArr[0].ItemArray.Length;//获取数据表第一行的列数,即属性个数
List<T> list = new List<T>();
for (int i = 0; i < rowArr.Length; i++)
{
T t = (T)Activator.CreateInstance(type);
for (int j = 0; j < len; j++)
{
propArr[j].SetValue(t, rowArr[i][j]);
}
list.Add(t);
t = default(T);
}
return list;
}
}
}
上面用到了泛型,反射,扩展方法。
之前在使用这行代码时出了点小问题:
propArr[i].SetValue(t, row[i]);
报了一个类型转换异常,断点调试之后发现是因为 Models 中的属性的排列和数据表的列的顺序不一样导致的,参照数据表中字段的顺序修改过来就好,还有一点就是在循环对属性进行赋值时,我选用的是数据表中列的个数,而不是属性的个数,(也就是代码中黄色部分)。
我对于扩展方法的理解:扩展方法有点类似于工具类,只不过将它和具体的类绑定在一起了。
C#中的反射和扩展方法的运用的更多相关文章
- C#中如果类的扩展方法和类本身的方法签名相同,那么会优先调用类本身的方法
新建一个.NET Core项目,假如我们有如下代码: using System; namespace MethodOverload { static class DemoExtension { pub ...
- java中的反射,invoke方法[转]
在施老师的项目中需要用到invoke,就是通过函数名反射相应的函数.一下代码简单地介绍了java反射中invoke方法,如果要具体的,可以参考魔乐核心课程的反射部分内容 package org.cur ...
- C# 通过反射获取扩展方法
注意,扩展方法本质上是静态方法,所以拿到MethodInfo时,应该这么调用 methodInfo.Invoke(null, new object[]{params}) static IEnumera ...
- .NET中使用反射访问属性方法
.net所编写的程序集包含两个重要部分:IL(中间语言代码) 和metadata(元数据).我们编写的代码中不是有很多很多的类吗,类有很多很多的成员,在编译代码的时候,元数据表就根据代码把类的所有信息 ...
- EasyUI中对datagrid的扩展方法
以下是给datagrid扩展一个方法的demo 1.给datagrid添加一个属性 $.extend($.fn.datagrid.defaults, { demo: "demo1" ...
- .NET中那些所谓的新语法之二:匿名类、匿名方法与扩展方法
开篇:在上一篇中,我们了解了自动属性.隐式类型.自动初始化器等所谓的新语法,这一篇我们继续征程,看看匿名类.匿名方法以及常用的扩展方法.虽然,都是很常见的东西,但是未必我们都明白其中蕴含的奥妙.所以, ...
- C#3.0中的扩展方法
在实际应用中,开发者完成代码的编译后,除非重新编译更改后的代码,否则开发者很难在原有代码中添加新的功能. 在C#3.0中,提供了一个扩展方法的新特性,可以使得开发者在编译后的程序集里边添加相关的方法, ...
- .NET: 谈谈C#中的扩展方法
扩展方法(Extension Methods)是C#3.0时引入的新特性,相信很多人都听过并且也都用过,最常见的是在LINQ中的使用. 不仅如此,在开发中,我们也可以创建自己扩展方法,使用它来优化类的 ...
- 关于C#中”扩展方法必须在非泛型静态类中定义“问题的解决
问题描述: 在某个窗口下的编码中使用了以下扩展方法FindControl,以求根据字符串的值去操作控件(本文中的控件为Label控件)的属性. public static Control FindCo ...
随机推荐
- Java设计模式(10)——结构型模式之代理模式(Proxy)
一.概述 概念 UML简图 实际使用的场景示例 如果那个对象是一个是很大的图片,需要花费很长时间才能显示出来,那么当这个图片包含在文档中时,使用编辑器或浏览器打开这个文档,打开文档必须很迅速,不能等待 ...
- 北京Uber优步司机奖励政策(12月12日)
用户组:人民优步及电动车(适用于12月12日) 滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:htt ...
- Kubernetes网络方案的三大类别和六个场景
欢迎访问网易云社区,了解更多网易技术产品运营经验. 本文章根据网易云资深解决方案架构师 王必成在云原生用户大会上的分享整理. 今天我将分享个人对于网络方案的理解,以及网易云在交付 Kubernetes ...
- hdu2094产生冠军(思维题)
产生冠军 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 在Linux CentOS7系统中搭建LNMP
LNMP就是Linux+Nginx+MySQL+PHP,既然是在Linux CentOS7那么Linux就是已经安装好了.所以接下百度一下接下来的教程,整理测试如下: 教程是centos6.2的有点老 ...
- Selenium(Python)PageObject页面对象
使用PageObject页面对象的好处是, 当页面元素的位置发生改变时, 只需要去修改Xpath或者ID, 而不用去修改测试用例本身: 本次的思路是: 1.常用方法类 2.页面对象类 3.测试用例类 ...
- Selenium安装(二)
安装python 安装Selenium之前首先来说一下Python,python是一门动态性语言,python的编写比较灵活,简洁,开发效率高.因此以python结合selenium来进行自动化测试. ...
- Java开发工程师(Web方向) - 01.Java Web开发入门 - 第3章.Tomcat
第3章--Tomcat Tomcat安装与运行 Tomcat:目前最常用的基于java的web应用服务器 本课程中所有的Java代码最终都需要部署到Tomcat中运行 Tomcat的配置文件是XML的 ...
- JavaScript 之 对象/JSON/数组
对象 简单说,所谓对象,就是一种无序的数据集合,由若干个“键值对”(key-value)构成. var obj = { p: 'Hello World' }; 上面代码中,大括号就定义了一个对象,它被 ...
- 最小生成树(II)与Kruskal算法
为防止网页加载过慢,故分两章.上接https://www.cnblogs.com/Uninstalllingyi/p/10479470.html Kruskal算法——将森林合并成树 玩过瘟疫公司吗… ...