Here is one general solution without reflecting properties. Use the extension method as shown below
public static DataTable ConvertToDataTable<TSource>(this IEnumerable<TSource> records, params Expression<Func<TSource, object>>[] columns) { var firstRecord = records.First(); if (firstRecord == null) return null; DataTable table = new DataTable(); List<Func<TSource, object>> functions = new List<Func<TSource, object>>(); foreach (var col in columns) { DataColumn column = new DataColumn(); column.Caption = (col.Body as MemberExpression).Member.Name; var function = col.Compile(); column.DataType = function(firstRecord).GetType(); functions.Add(function); table.Columns.Add(column); } foreach (var record in records) { DataRow row = table.NewRow(); int i = 0; foreach (var function in functions) { row[i++] = function((record)); } table.Rows.Add(row); } return table; }
And invoke the same when the parameters will be the column name in the order you want.
var table = records.ConvertToDataTable( item => item.Title, item => item.Street, item => item.City );
source share