Datatable is much more convenient than Ilist operations in some aspects, especially when some old programs are modified, the client has been bound to Dataset or datatable, if they are re-bound to Ilist, a lot of work will be done.
It is much easier to convert to able.
Public class CADataConverter
{
Private static Hashtable types = new Hashtable ();
Private CADataConverter ()
{
}
/** // <Summary>
/// Converts an IList into a datatable.
/// </Summary>
/// <Param name = "list"> List of objects. First item can not be null </param>
/// <Returns> </returns>
Public static DataTable ToDataTable (IList list)
{
If (list = null)
Throw new ArgumentNullException ("list", "List can not be null ");
If (list. Count = 0)
Throw new ArgumentOutOfRangeException ("list", "List can not be empty without supplying a type. Please use the other overload ");
Object obj = list [0];
If (obj = null)
Throw new ArgumentOutOfRangeException ("list", "First item in collection can not equal null ");
Return ToDataTable (list, obj. GetType ());
}
/** // <Summary>
/// Converts an IList into a datatable.
/// </Summary>
/// <Param name = "list"> </param>
/// <Param name = "t"> Since a type is supplied, the list can be null or empty </param>
/// <Returns> </returns>
Public static DataTable ToDataTable (IList list, Type t)
{
DataTable dt = types [t] as DataTable;
If (dt = null)
Dt = CreateShell (t );
Else
Dt = dt. Clone ();
If (list = null | list. Count = 0)
Return dt;
Foreach (object item in list)
{
If (item! = Null)
{
DataRow dr = dt. NewRow ();
Foreach (DataColumn dc in dt. Columns)
{
Try
{
Dr [dc. ColumnName] = t. GetProperty (dc. ColumnName). GetValue (item, null );
}
Catch {}
}
Dt. Rows. Add (dr );
}
}
Return dt;
}
/** // <Summary>
/// Creates a datatable with datacolumns
/// </Summary>
/// <Param name = "t"> </param>
/// <Returns> </returns>
Protected static DataTable CreateShell (Type t)
{
DataTable dt = new DataTable (t. Name );
PropertyInfo [] pia = t. GetProperties ();
Foreach (PropertyInfo pi in pia)
{
If (pi. CanRead)
{
String st = pi. PropertyType. ToString ();
Switch (st)
{
Case "System. String ":
Case "System. Int32 ":
Case "System. Boolean ":
Case "System. Double ":
Case "System. Guid ":
Dt. Columns. Add (pi. Name, pi. PropertyType );
Break;
}
}
}
Types [t] = dt;
Return dt;
}
}
The Type information is obtained through reflection. The type attribute is used as the column name. CreatShell implements
Type attribute value as a row. TODatatable implementation
Call:
DataTable dt = CADataConverter. ToDataTable (categories, typeof (PostCategory ));