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 ...
随机推荐
- 使用C语言协助办公_02批量修改学生信息
最新录制了一个使用C语言批量修改学生信息的视频,主要是讲了如何处理文件路径以及批量修改的思路.灵感来源于需要将整个17级社保照片按规格改名字.具体见:https://chuanke.baidu.com ...
- 常用的go语言IDE对比
Go语言目前已经在开发者中越发的流行,自然很多人都在寻找合适的IDE来实现代码语法高亮.自动补全以及其他编辑特性. 下面就几种常用的IDE进行对比介绍: 1. Sublime text 这个文本编辑器 ...
- MapWinGIS使用
.net语言中使用MapWinGIS.ocx http://www.cnblogs.com/kekec/archive/2011/03/30/1999709.html 基于MapWinGis的开发探索 ...
- 【LG2481】[SDOI2011]拦截导弹
[LG2481][SDOI2011]拦截导弹 题面 洛谷 题解 可以看出第一问就是一个有关偏序的\(LIS\),很显然可以用\(CDQ\)优化 关键在于第二问 概率\(P_i=\) \(总LIS数\) ...
- 【白书训练指南】(UVa10755)Garbage Heap
先po代码,之后把我那几个不太明了的知识点讲讲,巩固以下.三维的扫描线算法想要掌握还真是有一定的难度的. 代码 #include <iostream> #include <cstri ...
- 新的征程 in ZJU
争取考上了心仪的学校 并进入了心仪的实验室 但是对我来说,未来将是更多的挑战 首先我觉得我学习能力还是不足,无法做到一天的高效率学习 实验室的方向是可视化,我觉得这个是个非常复杂的方向 数学,pyth ...
- hibernate.hbm2ddl.auto=update不能自动生成表结构
在写上篇文章<spring整合springmvc和hibernate>的时候,曾遇到一个问题 INFO: Server startup in 8102 ms Hibernate: inse ...
- Request对象及常用方法
Object getAttribute(String name) 获得name的属性,若不存在,则返回null Enumeration getAttributeNames() 返回一个枚举类型的包含r ...
- 365. Count 1 in Binary【LintCode java】
Description Count how many 1 in binary representation of a 32-bit integer. Example Given 32, return ...
- 交换学生 (Foreign Exchange,UVa10763)
题目描述: 解题思路: 开一个数组,读入一次交换两个数,如果最后数组不变,即符合匹配 #include<iostream> #include<cstdio> #include& ...