vwd*_*aal 30 .net c# oop reflection
我刚刚学习了Generics,我想知道我是否可以用它来动态地从我的类中构建数据表.
或者我可能会忽略这一点.这是我的代码,我要做的是从我现有的类创建一个数据表并填充它.但是我陷入了思考过程中.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Data;
namespace Generics
{
public class Dog
{
public string Breed { get; set; }
public string Name { get; set; }
public int legs { get; set; }
public bool tail { get; set; }
}
class Program
{
public static DataTable CreateDataTable(Type animaltype)
{
DataTable return_Datatable = new DataTable();
foreach (PropertyInfo info in animaltype.GetProperties())
{
return_Datatable.Columns.Add(new DataColumn(info.Name, info.PropertyType));
}
return return_Datatable;
}
static void Main(string[] args)
{
Dog Killer = new Dog();
Killer.Breed = "Maltese Poodle";
Killer.legs = 3;
Killer.tail = false;
Killer.Name = "Killer";
DataTable dogTable = new DataTable();
dogTable = CreateDataTable(Dog);
//How do I continue from here?
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,DataTable它出错了.另外,作为反射和泛型的新手,我将如何使用Killer类实际填充数据?
Dav*_*yan 81
在所有以前的答案的基础上,这是一个从任何集合创建DataTable的版本:
public static DataTable CreateDataTable<T>(IEnumerable<T> list)
{
Type type = typeof(T);
var properties = type.GetProperties();
DataTable dataTable = new DataTable();
foreach (PropertyInfo info in properties)
{
dataTable.Columns.Add(new DataColumn(info.Name, Nullable.GetUnderlyingType(info.PropertyType) ?? info.PropertyType));
}
foreach (T entity in list)
{
object[] values = new object[properties.Length];
for (int i = 0; i < properties.Length; i++)
{
values[i] = properties[i].GetValue(entity);
}
dataTable.Rows.Add(values);
}
return dataTable;
}
Run Code Online (Sandbox Code Playgroud)
我最喜欢的自制功能.它可以同时创建和填充所有内容.抛出任何物体.
public static DataTable ObjectToData(object o)
{
DataTable dt = new DataTable("OutputData");
DataRow dr = dt.NewRow();
dt.Rows.Add(dr);
o.GetType().GetProperties().ToList().ForEach(f =>
{
try
{
f.GetValue(o, null);
dt.Columns.Add(f.Name, f.PropertyType);
dt.Rows[0][f.Name] = f.GetValue(o, null);
}
catch { }
});
return dt;
}
Run Code Online (Sandbox Code Playgroud)
这是David答案的更紧凑版本,它也是扩展功能。我已经在Github的C#项目中发布了代码。
public static class Extensions
{
public static DataTable ToDataTable<T>(this IEnumerable<T> self)
{
var properties = typeof(T).GetProperties();
var dataTable = new DataTable();
foreach (var info in properties)
dataTable.Columns.Add(info.Name, Nullable.GetUnderlyingType(info.PropertyType)
?? info.PropertyType);
foreach (var entity in self)
dataTable.Rows.Add(properties.Select(p => p.GetValue(entity)).ToArray());
return dataTable;
}
}
Run Code Online (Sandbox Code Playgroud)
我发现,这与将DataTable写入CSV的代码结合使用非常有效。
该错误可以通过更改以下内容来解决:
dogTable = CreateDataTable(Dog);
Run Code Online (Sandbox Code Playgroud)
对此:
dogTable = CreateDataTable(typeof(Dog));
Run Code Online (Sandbox Code Playgroud)
但您尝试做的事情有一些警告。首先, aDataTable不能存储复杂类型,因此如果它Dog有一个实例Cat,您将无法将其添加为列。在这种情况下,你想做什么取决于你,但请记住这一点。
其次,我建议您使用 a 的唯一时间DataTable是当您构建对其所消耗的数据一无所知的代码时。这有有效的用例(例如用户驱动的数据挖掘工具)。如果实例中已有数据Dog,则只需使用它即可。
另一个小花絮,是这样的:
DataTable dogTable = new DataTable();
dogTable = CreateDataTable(Dog);
Run Code Online (Sandbox Code Playgroud)
可以简化为:
DataTable dogTable = CreateDataTable(Dog);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
67049 次 |
| 最近记录: |