创建动态对象

时间:2012-09-14 15:11:37

标签: c# .net list object dynamic

如何动态创建对象?

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

虚构的类(代码中没有类):

class Employee
{
    string EmpName { get;set; }
    string EmpID { get;set; }
    string PhoneNo { get;set; }
}

注意:属性/列名称是动态的。

现在我想将List<Dictionary<string, object>>转换为List<object>类型(即{}} {。}}。

可能吗?建议请。

3 个答案:

答案 0 :(得分:21)

使用匿名对象(如果您知道要投影的属性):

var employees = 
    (from dict in testData 
        select new 
        { 
            EmpName = dict["EmpName"] as string, 
            EmpID= dict["EmpID"] as string, 
            PhoneNo=dict["PhoneNo"] as string 
        }).ToList();

或者,使用System.Dynamic.Expando(如果需要动态投影未知的列名):

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

答案 1 :(得分:2)

编辑建议“发射”。

鉴于你甚至不知道列名,我会使用Reflection.Emit来动态创建Employee类。有关如何使用Emit的信息,请参阅http://msdn.microsoft.com/en-us/library/3y322t50(v=vs.100).aspx。伪代码将是:

ReflectionEmit("Employee", columns);
List<object> newList = testData.Select<object>(p => {
    var employee = ReflectionInstantiate("Employee");
    foreach column in columns
         Reflection.SetProperty(employee, column, p[column]);
    });

真正的代码会更复杂,因为Emit并不简单。 :)

答案 2 :(得分:1)

是的,这是可能的,但不是很简单。

您可以动态定义类型,例如通过CodeDOM或使用Reflection.Emit。通常,您的应用程序将生成代码模型(CodeDOM)或IL指令(Reflection.Emit)以构建新类型。根据您的需要,您甚至可以保存生成的dll并在以后使用它。

例如,这是如何在.NET中生成序列化程序集的:检查要序列化的类型,并专门为该类型生成自定义序列化程序类,以便序列化不必依赖于在运行时反思。