C# 创建动态对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12427280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 23:15:13  来源:igfitidea点击:

Creating Dynamic Objects

c#.netlistobjectdynamic

提问by Ramesh Durai

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

现在我想将 the 转换List<Dictionary<string, object>>为类型List<object>(ie) 的类List<Employee>

Is it Possible? Suggestions please.

是否可以?请提出建议。

采纳答案by Tetsujin no Oni

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

或者,使用 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);
}

回答by Tombala

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).aspxfor information on how to use Emit. The pseudo code will then be:

鉴于您甚至不知道列名,我将使用 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]);
    });

The real code will be a little more complicated as Emit is not straightforward. :)

真正的代码会稍微复杂一些,因为 Emit 并不简单。:)

回答by Zdeslav Vojkovic

Yes it is possible, but not quite simple.

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

You can define types dynamically, e.g. via CodeDOMor 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.

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

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.

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