c#中利用委托反射将DataTable转换为实体集的代码_C#教程

类泛型的约束:

复制代码 代码如下:

public static class ToModel<T> where T : class, new()

定义委托:

复制代码 代码如下:

public delegate void SetString(string value);

创建委托方法:

复制代码 代码如下:

private static SetString CreateStringDelegate(T model, string propertyName)
{
MethodInfo mi = model.GetType().GetProperty(propertyName).GetSetMethod();
Type type = typeof(SetString);
return Delegate.CreateDelegate(type, model, mi) as SetString;
}

利用反射和委托将DataTable转换为实体集:

复制代码 代码如下:

public static IList<T> GetDelegate_ToModelList(DataTable dt)
{
IList<T> list = new List<T>();
if (dt == null || dt.Rows.Count < 1) return list;
SetString setDelegateString;
foreach (DataRow dr in dt.Rows)
{
T model = new T();
foreach (DataColumn dc in dt.Columns)
{
setDelegateString = CreateStringDelegate(model, dc.ColumnName);
setDelegateString(dr[dc.ColumnName].ToString());
}
list.Add(model);
}
return list;
}

这样写问题就来了,因为委托定义的参数时string类型的,因为我们实体中可能有int或者DateTime类型的,这时就需要用上泛型委托了
如果这样定义委托:

复制代码 代码如下:

public delegate void SetString<PT>(PT value)

创建委托方法(这里有问题,不知如何处理):

复制代码 代码如下:

private static SetString CreateStringDelegate(T model, string propertyName)
{
MethodInfo mi = model.GetType().GetProperty(propertyName).GetSetMethod();
Type type = typeof(model).GetProperty(propertyName).PropertyType;
return Delegate.CreateDelegate(type, model, mi) as SetString<type>;
}

利用反射和委托将DataTable转换为实体集:

复制代码 代码如下:

public static IList<T> GetDelegate_ToModelList(DataTable dt)
{
IList<T> list = new List<T>();
if (dt == null || dt.Rows.Count < 1) return list;
foreach (DataRow dr in dt.Rows)
{
T model = new T();
foreach (DataColumn dc in dt.Columns)
{
SetString<typeof(T).GetProperty(dc.ColumnName).PropertyType> setDelegateString = CreateStringDelegate(model, dc.ColumnName);
setDelegateString(dr[dc.ColumnName].ToString());
}
list.Add(model);
}
return list;
}

一直疑惑着,希望有人帮我解决疑惑,直接反射的方法我也有,但是这个问题不解决,心里一直有疙瘩,希望有人帮帮忙,谢谢
泛型可以动态构建的,你了解了这个,就能解决了,附上我的简略代码:

复制代码 代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Reflection;
namespace RftToModel {
class Program {
static void Main(string[] args) {
var result = ToModel<TestModel>.GetDelegate_ToModelList(BuildSampleTable());
foreach (var item in result) {
Console.WriteLine(item);
}
Console.Read();
}
static DataTable BuildSampleTable() {
DataTable result = new DataTable();
result.Columns.Add("ID", typeof(int));
result.Columns.Add("Name", typeof(string));
result.Columns.Add("IsDeleted", typeof(bool));
result.Rows.Add(new object[] { 1, "M.K", false });
result.Rows.Add(new object[] { 2, "B.G", true });
return result;
}
}
public class TestModel {
public int ID { get; set; }
public string Name { get; set; }
public bool IsDeleted { get; set; }
public override string ToString() {
return string.Format("ID:{0} Name:{1} IsDeleted:{2}", ID, Name, IsDeleted);
}
}
public delegate void SetValue<T>(T value);
public static class ToModel<T> where T : class, new() {
private static Delegate CreateSetDelegate(T model, string propertyName) {
MethodInfo mi = model.GetType().GetProperty(propertyName).GetSetMethod();
//这里构造泛型委托类型
Type delType = typeof(SetValue<>).MakeGenericType(GetPropertyType(propertyName));
return Delegate.CreateDelegate(delType, model, mi);
}
private static Type GetPropertyType(string propertyName) {
return typeof(T).GetProperty(propertyName).PropertyType;
}
public static IList<T> GetDelegate_ToModelList(DataTable dt) {
IList<T> list = new List<T>();
if (dt == null || dt.Rows.Count < 1) return list;
Delegate setDelegate;
foreach (DataRow dr in dt.Rows) {
T model = new T();
foreach (DataColumn dc in dt.Columns) {
setDelegate = CreateSetDelegate(model, dc.ColumnName);
//这里改变类型
setDelegate.DynamicInvoke(Convert.ChangeType(dr[dc.ColumnName], GetPropertyType(dc.ColumnName)));
}
list.Add(model);
}
return list;
}
}
}

谢谢,我刚修改了,我传进去SqlDataReader和DataTable都可以转换了,当时只想着每次返回一个特定类型等委托都不知道如何下手,看着你的方法解决了
没想到DynamicInvoke这个方法,算是学习了,你的代码写着层次好清晰,看了是一种享受,向你学习啊!

时间: 2024-10-22 20:11:53

c#中利用委托反射将DataTable转换为实体集的代码_C#教程的相关文章

C#实现汉字转换为拼音缩写的代码_C#教程

本文实例为大家分享了C#汉字转换为拼音缩写的实现代码,供大家参考,具体内容如下 using System; using System.Configuration; using System.Data; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web

在.NET中利用委托实现窗体间通信

对于窗体间简单的通信,采用VB6.0的方法就能满足我们的要求,但在一些架构设计复杂的应用中,这种方法就显得有点捉襟见肘了,同时该方法还有一个缺点,就是它仅仅对通过.NET窗体向导添加进去的窗体起作用,而对于自定义的窗体类型我们是无法添加到Forms对象集合中的.而且也和其它诸如构造函数传参等方法一样,会在窗体间大量互相引用各自的成员,造成了彼此之间存在着很大的耦合性,非常不利于窗体模块间的独立,这不符合良好软件设计模式的思想. 如果我们想在一个窗体中访问另一个窗体中自定义的成员,必须把该成员的可

在.NET中利用委托实现窗体间通信_实用技巧

对于窗体间简单的通信,采用VB6.0的方法就能满足我们的要求,但在一些架构设计复杂的应用中,这种方法就显得有点捉襟见肘了,同时该方法还有一个缺点,就是它仅仅对通过.NET窗体向导添加进去的窗体起作用,而对于自定义的窗体类型我们是无法添加到Forms对象集合中的.而且也和其它诸如构造函数传参等方法一样,会在窗体间大量互相引用各自的成员,造成了彼此之间存在着很大的耦合性,非常不利于窗体模块间的独立,这不符合良好软件设计模式的思想. 如果我们想在一个窗体中访问另一个窗体中自定义的成员,必须把该成员的可

C#中利用正则表达式将人民币金额转换为大写汉字_Android

直接来看代码: public static string ConvertToChineseMoney(double money) { if (money < 0) throw new ArgumentOutOfRangeException("参数money不能为负值!"); string s = money.ToString("#L#E#D#C#K#E#D#C#J#E#D#C#I#E#D#C#H#E#D#C#G#E#D#C#F#E#D#C#.0B0A"); s

C#中利用正则表达式将人民币金额转换为大写汉字

直接来看代码: public static string ConvertToChineseMoney(double money) { if (money < 0) throw new ArgumentOutOfRangeException("参数money不能为负值!"); string s = money.ToString("#L#E#D#C#K#E#D#C#J#E#D#C#I#E#D#C#H#E#D#C#G#E#D#C#F#E#D#C#.0B0A"); s

C#中委托(Delegates)的使用方法详解_C#教程

1. 委托是什么? 其实,我一直思考如何讲解委托,才能把委托说得更透彻.说实话,每个人都委托都有不同的见解,因为看问题的角度不同.个人认为,可以从以下2点来理解:  (1) 从数据结构来讲,委托是和类一样是一种用户自定义类型.  (2) 从设计模式来讲,委托(类)提供了方法(对象)的抽象. 既然委托是一种类型,那么它存储的是什么数据? 我们知道,委托是方法的抽象,它存储的就是一系列具有相同签名和返回回类型的方法的地址.调用委托的时候,委托包含的所有方法将被执行. 2. 委托类型的定义 委托是类型

C# DataTable中Compute方法用法集锦(数值/字符串/运算符/表等操作)_C#教程

本文实例讲述了C# DataTable中Compute方法用法.分享给大家供大家参考,具体如下: Compute函数的参数就两个:Expression,和Filter. Expresstion是计算表达式,关于Expression的详细内容请看这里: http://msdn2.microsoft.com/zh-cn/library/system.data.datacolumn.expression(VS.80).aspx 而Filter则是条件过滤器,类似sql的Where条件. DataTab

asp.net中利用正则表达式判断一个字符串是否为数字的代码_正则表达式

复制代码 代码如下: publicstaticbool IsNumeric(string value) { return Regex.IsMatch(value, @"^[+-]?\d*[.]?\d*$"); } publicstaticbool IsInt(string value) { return Regex.IsMatch(value, @"^[+-]?\d*$"); } publicstaticbool IsUnsign(string value) { r

C#从实体对象集合中导出Excel的代码_C#教程

或是将Datagrid或是Gridview的输出导出,实现大体上又分为调用COM+组件或是利用Response(当然是B/S架构的项目)的输出来做,COM+组件的方式以前在项目中也应用过,但说实话感觉效果并不好,一是布署很麻烦,二是当时记得好像WEB服务器端的有个进程老关不掉,并且还有个问题是服务器端安装的EXCEL版本的不同,在程序中调用的方法传入的参数个数都不相同,真是够郁闷的,但是好处是这种方式当然是最灵活的. 我们还是以一个B/S架构的项目应用来说说导出吧,通用一点儿的还是从数据集往外导