Creating Dynamic Objects

32,271

Solution 1

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);
}

Solution 2

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. :)

Solution 3

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.

Share:
32,271
Ramesh Durai
Author by

Ramesh Durai

..

Updated on July 22, 2020

Comments

  • Ramesh Durai
    Ramesh Durai almost 4 years

    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.