这是使用NuGet的FastMember进行的 2013年不错的更新:
IEnumerable<SomeType> data = ...DataTable table = new DataTable();using(var reader = ObjectReader.Create(data)) { table.Load(reader);}这使用FastMember的元编程API以获得最佳性能。如果要将其限制为特定成员(或强制执行命令),则也可以这样做:
IEnumerable<SomeType> data = ...DataTable table = new DataTable();using(var reader = ObjectReader.Create(data, "Id", "Name", "Description")) { table.Load(reader);}编辑的 Dis /声明者 : FastMember是Marc Gravell的项目。它的黄金和全蝇!
是的,这与这个完全相反。反射就足够了-
或者如果您需要更快,则
HyperDescriptor在2.0或
expression3.5中。实际上,
HyperDescriptor应该绰绰有余。
例如:
// remove "this" if not on C# 3.0 / .NET 3.5public static DataTable ToDataTable<T>(this IList<T> data){ PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T)); DataTable table = new DataTable(); for(int i = 0 ; i < props.Count ; i++) { PropertyDescriptor prop = props[i]; table.Columns.Add(prop.Name, prop.PropertyType); } object[] values = new object[props.Count]; foreach (T item in data) { for (int i = 0; i < values.Length; i++) { values[i] = props[i].GetValue(item); } table.Rows.Add(values); } return table; }现在只需一行,您就可以使它比反射快很多倍(通过启用
HyperDescriptorobject-
type
T)。
编辑再绩效查询;这是带有结果的测试台:
Vanilla 27179Hyper 6997
我怀疑瓶颈已经从成员访问转变为
DataTable绩效…我怀疑您会在此方面做很多改进…
码:
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Diagnostics;public class MyData{ public int A { get; set; } public string B { get; set; } public DateTime C { get; set; } public decimal D { get; set; } public string E { get; set; } public int F { get; set; }}static class Program{ static void RunTest(List<MyData> data, string caption) { GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); GC.WaitForFullGCComplete(); Stopwatch watch = Stopwatch.StartNew(); for (int i = 0; i < 500; i++) { data.ToDataTable(); } watch.Stop(); Console.WriteLine(caption + "t" + watch.ElapsedMilliseconds); } static void Main() { List<MyData> foos = new List<MyData>(); for (int i = 0 ; i < 5000 ; i++ ){ foos.Add(new MyData { // just gibberish... A = i, B = i.ToString(), C = DateTime.Now.AddSeconds(i), D = i, E = "hello", F = i * 2 }); } RunTest(foos, "Vanilla"); Hyper.ComponentModel.HyperTypeDescriptionProvider.Add( typeof(MyData)); RunTest(foos, "Hyper"); Console.ReadLine(); // return to exit }}


