Reputation: 315
Is it possible to cast a type from a variable? I'm extracting data from a spreadsheet into a class, but because some columns are strings, and others DateTime, I really want a do-all command, that I don't need to map everything manually.
What I have so far:
foreach (PropertyInfo pinfo in asset.GetType().GetProperties())
{
string columnType = (from DataColumn column in data.Columns where column.ColumnName == pinfo.Name select column).First().DataType.ToString();
pinfo.SetValue(asset, row.Field<columnType>(pinfo.Name));
}
At the moment, it doesn't like row.Field<columnType>()
, because it's not a real type.
Is it possible to do something like the above, where I'm getting the type contained in a column, and casting this to retrieve the data for that column? I'm in this situation, as I want to retrieve anything using the following statement, regardless of whether it's a string, int or DateTime.
var foo = row.Field<string>("Column Name");
Is there any generic command I can use? Thanks
Upvotes: 0
Views: 1551
Reputation: 236328
PropertyInfo.SetValue accepts value as object. If your DataTable has column of appropriate type, then just get column value with row[columnName]
which also will be returned as object, and use it to set property value:
foreach (PropertyInfo pinfo in asset.GetType().GetProperties())
{
pinfo.SetValue(asset, row[pinfo.Name]);
}
Sample: consider you have class
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
And you have DataTable which has columns with appropriate types:
DataTable dt = new DataTable();
dt.Columns.Add("Id", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Rows.Add(1, "Bob");
dt.Rows.Add(2, "John");
Then filling user from DataTable will look like:
var user = new User();
var row = dt.Rows[0];
foreach (PropertyInfo pinfo in user.GetType().GetProperties())
pinfo.SetValue(user, row[pinfo.Name]);
NOTE: You can skip properties which don't have appropriate type, also you can handle case when there is no column with property name:
foreach (PropertyInfo pinfo in user.GetType().GetProperties())
{
if (!dt.Columns.Contains(pinfo.Name) ||
dt.Columns[pinfo.Name].DataType != pinfo.PropertyType)
continue;
pinfo.SetValue(user, row[pinfo.Name]);
}
Upvotes: 2