Reputation: 2686
How to dynamically create objects?
string[] columnNames = { "EmpName", "EmpID", "PhoneNo" };
List<string[]> columnValues = new List<string[]>();
for (int i = 0; i < 10; i++)
{
columnValues.Add(new[] { "Ramesh", "12345", "12345" });
}
List<Dictionary<string, object>> testData = new List<Dictionary<string, object>>();
foreach (string[] columnValue in columnValues)
{
Dictionary<string, object> data = new Dictionary<string, object>();
for (int j = 0; j < columnNames.Count(); j++)
{
data.Add(columnNames[j], columnValues[j]);
}
testData.Add(data);
}
Imaginary Class(Class is not available in code):
class Employee
{
string EmpName { get;set; }
string EmpID { get;set; }
string PhoneNo { get;set; }
}
Note: Property/column names are dynamic.
Now I want to convert the List<Dictionary<string, object>>
to a class of type List<object>
(i.e) List<Employee>
.
Is it Possible? Suggestions please.
Upvotes: 7
Views: 32831
Reputation: 7367
Using an anonymous object (if you know the properties you want to project):
var employees =
(from dict in testData
select new
{
EmpName = dict["EmpName"] as string,
EmpID= dict["EmpID"] as string,
PhoneNo=dict["PhoneNo"] as string
}).ToList();
Or, using System.Dynamic.Expando (if you need to dynamically project unknown column names):
string[] columnNames = { "EmpName", "EmpID", "PhoneNo" };
List<string[]> columnValues = new List<string[]>();
for (int i = 0; i < 10; i++)
{
columnValues.Add(new[] { "Ramesh", "12345", "12345" });
}
var testData = new List<ExpandoObject>();
foreach (string[] columnValue in columnValues)
{
dynamic data = new ExpandoObject();
for (int j = 0; j < columnNames.Count(); j++)
{
((IDictionary<String,Object>)data).Add(columnNames[j], columnValue[j]);
}
testData.Add(data);
}
Upvotes: 21
Reputation: 1690
Edited to suggest "Emit".
In light of the fact that you don't even know the column names, I would use Reflection.Emit to first create the Employee class on the fly. See http://msdn.microsoft.com/en-us/library/3y322t50(v=vs.100).aspx for information on how to use Emit. The pseudo code will then be:
ReflectionEmit("Employee", columns);
List<object> newList = testData.Select<object>(p => {
var employee = ReflectionInstantiate("Employee");
foreach column in columns
Reflection.SetProperty(employee, column, p[column]);
});
The real code will be a little more complicated as Emit is not straightforward. :)
Upvotes: 2
Reputation: 14591
Yes it is possible, but not quite simple.
You can define types dynamically, e.g. via CodeDOM or using Reflection.Emit. In general, you application will generate code model (CodeDOM) or IL instrucions (Reflection.Emit) in order to build a new type. Depending on your needs, you can even save the generated dlls and use it later.
This is for example, how serializer assemblies are generated in .NET: the type which is to be serialized is inspected, and custom serializer classes are generated specifically for that type, so that serialization doesn't have to rely on reflection in runtime.
Upvotes: 1