Why Convert List to DataTable?
Here are some common scenarios where this conversion becomes necessary.
- Binding data to GridView in Web Forms.
- Exporting data to Excel or PDF.
- Passing structured data as a SqlParameter to a stored procedure (Table-Valued Parameters).
- Interoperability with legacy ADO.NET code.
Sample Class
Let’s say you have a simple class like this.
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime BirthDate { get; set; }
}
You have a list of Person.
List<Person> people = new List<Person>
{
new Person { Id = 1, Name = "Alice", BirthDate = new DateTime(1990, 1, 1) },
new Person { Id = 2, Name = "Bob", BirthDate = new DateTime(1995, 5, 23) },
new Person { Id = 3, Name = "Nic", BirthDate = new DateTime(1990, 2, 10) },
new Person { Id = 4, Name = "Jon", BirthDate = new DateTime(1994, 3, 4) }
};
You can create an extension method to convert any List<T> to a DataTable.
public static class ListToDataTableConverter
{
public static DataTable ToDataTable<T>(this List<T> items)
{
DataTable table = new DataTable(typeof(T).Name);
try
{
PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var prop in properties)
{
Type propType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
table.Columns.Add(prop.Name, propType);
}
foreach (var item in items)
{
var values = properties.Select(p => p.GetValue(item, null)).ToArray();
table.Rows.Add(values);
}
}
catch (Exception)
{
table = new DataTable();
}
return table;
}
}
Using the Method here using Blazor application.
protected override void OnInitialized()
{
DataTable dataTable = getData();
}
private DataTable getData()
{
List<Person> people = new List<Person>
{
new Person { Id = 1, Name = "Alice", BirthDate = new DateTime(1990, 1, 1) },
new Person { Id = 2, Name = "Bob", BirthDate = new DateTime(1995, 5, 23) },
new Person { Id = 3, Name = "Nic", BirthDate = new DateTime(1990, 2, 10) },
new Person { Id = 4, Name = "Jon", BirthDate = new DateTime(1994, 3, 4) }
};
DataTable dataTable = people.ToDataTable();
return dataTable;
}
Output

Advantages
- Generic: Works with any object type.
- Reusable: Just call.ToDataTable() on your list.
- No third-party dependencies.
Tips
- If you want only selected properties, you can modify the method to take a list of property names.
- For complex/nested properties, you'll need a recursive approach or flatten the structure.
Conclusion
This technique is a lifesaver when working with ADO.NET, reporting, or data exports in enterprise applications. By using reflection, we avoid hardcoding columns and make the method generic and reusable.

Join the conversation! Your thoughts help the community grow.