如何运用Reflection转化DynamicObject和Generic集合为DataTable

本文介绍了一种方法,用于将由DAL产生的PocoCollection转换为DataTable,并将其传递给报表处理模块。通过实例代码展示了如何根据不同类型的T(包括DynamicObject)进行灵活的类型判断和属性映射。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

正在做的项目里面有需要把DAL 产生的Poco Collection转为DataTable然后交给别的模块处理报表

想了一下 写个支持Generic的方法吧, 不过不知道如何判断 T是否是DynamicObject的类型

于是取了第一个item,用它来判断一下,这样写肯定不是最好的,把code贴上抛砖引玉。

public static DataTable ToDataTable<T>(IEnumerable<T> input, string tableName)
{
var dt = new DataTable();
dt.TableName = tableName;

var first = Enumerable.First(input);

if (first is System.Dynamic.DynamicObject)
{
IDictionary<string, object> properties = (IDictionary<string, object>)first;

foreach (var p in properties)
{
var type = p.Value.GetType();
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
type = type.GetGenericArguments()[0];

dt.Columns.Add(p.Key, type);
}

foreach (T r in input)
{
var values = new object[properties.Count];
int i = 0;
foreach (var p in properties)
{
values[i] = (r as IDictionary<string, object>)[p.Key];
i++;
}

dt.LoadDataRow(values, true);
}
}

else
{
var properties = typeof(T).GetProperties();

foreach (var p in properties)
{
var type = p.PropertyType;
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
type = type.GetGenericArguments()[0];

dt.Columns.Add(p.Name, type);
}

foreach (T r in input)
{
var values = new object[properties.Length];
int i = 0;
foreach (var p in properties)
{
values[i] = p.GetValue(r, null);
i++;
}

dt.LoadDataRow(values, true);
}
}
return dt;
}



转载于:https://www.cnblogs.com/gunsmoke/archive/2011/10/20/2218787.html

### C# 中 `DynamicObject` 的赋值 在 C# 中,`DynamicObject` 是一种特殊的类,允许创建具有动态属性的对象。为了给 `DynamicObject` 赋值,通常会继承 `System.Dynamic.DynamicObject` 并重写其方法以定义行为。 #### 创建初始化 `DynamicObject` 可以通过继承 `DynamicObject` 来创建自定义的动态对象,并通过设置字段或属性来进行赋值: ```csharp using System; using System.Dynamic; public class MyDynamic : DynamicObject { private Dictionary<string, object> _properties = new Dictionary<string, object>(); public override bool TrySetMember(SetMemberBinder binder, object value) { // 将成员名称作为键存入字典中 _properties[binder.Name] = value; return true; } public override bool TryGetMember(GetMemberBinder binder, out object result) { // 如果存在则返回对应的值;否则返回 null return _properties.TryGetValue(binder.Name, out result); } } // 使用示例 MyDynamic obj = new MyDynamic(); obj.PropertyName = "PropertyValue"; // 动态添加属性并赋值 Console.WriteLine(obj.PropertyName); // 输出 PropertyValue ``` 此代码展示了如何利用 `TrySetMember` 方法拦截对不存在成员的赋值操作[^1]。 对于更简单的场景,如果不需要完全控制动态行为,则可以直接使用内置的 `ExpandoObject` 类,它提供了更为简便的方式来管理动态属性: ```csharp dynamic expandoObj = new ExpandoObject(); expandoObj.NewProperty = "Some Value"; Console.WriteLine(expandoObj.NewProperty); // Some Value ``` 上述例子中的 `ExpandoObject` 可以像常规对象一样轻松地为其新增任意数量的新属性,并且这些新属性可以在后续的操作中正常读取修改[^2]。 当涉及到复杂的数据结构或者需要更加灵活的行为时,建议采用扩展 `DynamicObject` 的方式来自定义逻辑。而对于简单的需求来说,`ExpandoObject` 提供了一个快速而有效的解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值