I have a list where I select column TaskId
(Global variable) and EmpGuid
(from list) like:
var parameterstest = assignNotificationTableType.Select(x => new { TaskId, x.EmpGuid }).ToList();
So if I debug I get something like this:
Now I create method to convert it to DataTable like:
public static DataTable ToDataTable<T>(List<T> items)
{
DataTable dataTable = new DataTable(typeof(T).Name);
//Get all the properties
PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
if (Props.Length > 0)
{
foreach (PropertyInfo prop in Props)
{
if (GetDefault(prop.PropertyType.FullName) != null)
{
//Setting column names as Property names
dataTable.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
}
}
}
else
{
dataTable.Columns.Add("myColName");
}
foreach (T item in items)
{
if (item != null)
{
DataRow dr = dataTable.NewRow();
if (Props.Length > 0)
{
foreach (PropertyInfo prop in Props)
{
if (GetDefault(prop.PropertyType.FullName) != null)
{
//inserting property values to datatable rows
dr[prop.Name] = prop.GetValue(item, null) ?? GetDefault(prop.PropertyType.FullName);
}
}
}
else
{
//inserting property values to datatable rows
dr[0] = item;
}
dataTable.Rows.Add(dr);
}
}
//put a breakpoint here and check datatable
return dataTable;
}
public static object GetDefault(string dataType)
{
if (dataType.Contains("System.String"))
{
return string.Empty;
}
if (dataType.Contains("System.Boolean"))
{
return false;
}
if (dataType.Contains("System.Decimal"))
{
return 0.0;
}
if (dataType.Contains("System.DateTime"))
{
return DateTime.MinValue;
}
if (dataType.Contains("System.Int64"))
{
return 0;
}
if (dataType.Contains("System.Guid"))
{
return null;
}
if (dataType.Contains("System.Int16"))
{
return 0;
}
if (dataType.Contains("Int32"))
{
return 0;
}
if (dataType.Contains("System.Object"))
{
return null;
}
return null;
}
But when I try to use as:
var parameters = ToDataTable(assignNotificationTableType.Select(x => new { TaskId, x.EmpGuid }).ToList());
Variable returns {<>f__AnonymousType42}
instead DataTable
I don't know why it returns AnonymousType. Some one know what is the issue there?
UPDATE
As you can see Anonymous type datatable count rows correctly but ItemArray is always zero instead my values
I solved it changing my Convert DataTable method to:
public static DataTable ToSingleDataTable<T>(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;
}
With dynamic
variables, the C# compiler adds code to figure out the type of the variable and perform necessary operations on it, all at run time.
Generics in C# are reified at compile-time; that is, if you have List<T>
and construct it with new List<int>()
, during the compilation phase a new completely class (named, I believe, "List`1[Int32]") will be generated and included in the binary. The invocation new List<int>()
will be replaced with the constructor of this new class (contrast this with Java, which does type erasure on its generics rather than type reification, so everything ends up an ArrayList
containing Object
s, effectively an ArrayList<Object>
).
Maybe you see where this is going. To compile your function that creates a DataTable<T>
, the compiler has to know the type of T
at compile time - precisely what dynamic
has already told the compiler to defer and figure out at run time. Therefore, every time you say DataTable<T>
where T
is dynamic
, the compiler has to put in a placeholder: hence the AnonymousType. The debugger doesn't know more, because the debug symbols are added at compile time, too.
If you can't view the items contained in the DataTable by clicking the disclosure triangle, you should still be able to view them if you go to the Debugger command line, with ? parameters
? parameters
and/or ? paramaters.Columns[<name>]
? paramaters.Columns[<name>]
, etc
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.