C#中的反射和扩展方法的运用

时间:2023-01-01 14:56:41

前段时间做了一个练手的小项目,采用的是三层架构,也就是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#中的反射和扩展方法的运用的更多相关文章

  1. C&num;中如果类的扩展方法和类本身的方法签名相同,那么会优先调用类本身的方法

    新建一个.NET Core项目,假如我们有如下代码: using System; namespace MethodOverload { static class DemoExtension { pub ...

  2. java中的反射,invoke方法&lbrack;转&rsqb;

    在施老师的项目中需要用到invoke,就是通过函数名反射相应的函数.一下代码简单地介绍了java反射中invoke方法,如果要具体的,可以参考魔乐核心课程的反射部分内容 package org.cur ...

  3. C&num; 通过反射获取扩展方法

    注意,扩展方法本质上是静态方法,所以拿到MethodInfo时,应该这么调用 methodInfo.Invoke(null, new object[]{params}) static IEnumera ...

  4. &period;NET中使用反射访问属性方法

    .net所编写的程序集包含两个重要部分:IL(中间语言代码) 和metadata(元数据).我们编写的代码中不是有很多很多的类吗,类有很多很多的成员,在编译代码的时候,元数据表就根据代码把类的所有信息 ...

  5. EasyUI中对datagrid的扩展方法

    以下是给datagrid扩展一个方法的demo 1.给datagrid添加一个属性 $.extend($.fn.datagrid.defaults, { demo: "demo1" ...

  6. &period;NET中那些所谓的新语法之二:匿名类、匿名方法与扩展方法

    开篇:在上一篇中,我们了解了自动属性.隐式类型.自动初始化器等所谓的新语法,这一篇我们继续征程,看看匿名类.匿名方法以及常用的扩展方法.虽然,都是很常见的东西,但是未必我们都明白其中蕴含的奥妙.所以, ...

  7. C&num;3&period;0中的扩展方法

    在实际应用中,开发者完成代码的编译后,除非重新编译更改后的代码,否则开发者很难在原有代码中添加新的功能. 在C#3.0中,提供了一个扩展方法的新特性,可以使得开发者在编译后的程序集里边添加相关的方法, ...

  8. &period;NET&colon; 谈谈C&num;中的扩展方法

    扩展方法(Extension Methods)是C#3.0时引入的新特性,相信很多人都听过并且也都用过,最常见的是在LINQ中的使用. 不仅如此,在开发中,我们也可以创建自己扩展方法,使用它来优化类的 ...

  9. 关于C&num;中”扩展方法必须在非泛型静态类中定义&OpenCurlyDoubleQuote;问题的解决

    问题描述: 在某个窗口下的编码中使用了以下扩展方法FindControl,以求根据字符串的值去操作控件(本文中的控件为Label控件)的属性. public static Control FindCo ...

随机推荐

  1. &OpenCurlyDoubleQuote;-webkit-appearance&colon; none”按钮样式作用!

    -webkit-appearance: none,可以去除浏览器默认样式.

  2. Chapter 3&period;GDI&sol;DirectDraw Internal Data Structures

    说明,在这里决定跳过第二章,实在是因为里面涉及的内容太理论,对我而言又太艰深 3.1 HANDLES AND OBJECT-ORIRNTED PROGRAMMING In normal object- ...

  3. JavaScript学习笔记-JSON对象

    JSON 是一种用来序列化对象.数组.数值.字符串.布尔值和 null 的语法.它基于 JavaScript 语法,但是又有区别:一些 JavaScript 值不是 JSON,而某些 JSON 不是 ...

  4. java8-4 多态的练习以及题目

    1./* 多态练习:猫狗案例*/ class Animal { public void eat(){ System.out.println("吃饭"); } } class Dog ...

  5. 为什么要web语义化

    为什么要web语义化 其实wiki的定义里面说得非常清晰了.语义化的好处有三点 有利于搜索 容易兼容不同设备 结构清晰,利于团队的开发.维护

  6. BZOJ 3589 动态树 树链拆分&plus;纳入和排除定理

    标题效果:鉴于一棵树.每个节点有一个右值,所有节点正确启动值他们是0.有两种操作模式,0 x y代表x右所有点的子树的根值添加y. 1 k a1 b1 a2 b2 --ak bk代表质疑. 共同拥有者 ...

  7. 第15课 右值引用(2)&lowbar;std&colon;&colon;move和移动语义

    1. std::move (1)std::move的原型 template<typename T> typename remove_reference<T>::type&amp ...

  8. e859&period; 将键盘事件和字符串对应

    The KeyStroke.toString() method does not return a string that can be parsed by KeyStroke.getKeyStrok ...

  9. 数学建模及机器学习算法(一):聚类-kmeans(Python及MATLAB实现,包括k值选取与聚类效果评估)

    一.聚类的概念 聚类分析是在数据中发现数据对象之间的关系,将数据进行分组,组内的相似性越大,组间的差别越大,则聚类效果越好.我们事先并不知道数据的正确结果(类标),通过聚类算法来发现和挖掘数据本身的结 ...

  10. HDU - 4676 :Sum Of Gcd (莫队&amp&semi;区间gcd公式)

    Given you a sequence of number a 1, a 2, ..., a n, which is a permutation of 1...n. You need to answ ...