7

オブジェクトを動的に作成する方法は?

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 Employee
{
    string EmpName { get;set; }
    string EmpID { get;set; }
    string PhoneNo { get;set; }
}

注:プロパティ/列名は動的です。

ここで、をタイプ(ie)List<Dictionary<string, object>>のクラスに変換したいと思います。List<object>List<Employee>

出来ますか?提案をお願いします。

4

3 に答える 3

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);
}
于 2012-09-14T15:15:47.603 に答える
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は単純ではないため、実際のコードはもう少し複雑になります。:)

于 2012-09-14T15:15:44.970 に答える
1

はい、それは可能ですが、非常に単純ではありません。

CodeDOMまたはReflection.Emitを使用して、型を動的に定義できます。一般に、アプリケーションは、新しいタイプを構築するために、コードモデル(CodeDOM)またはIL命令(Reflection.Emit)を生成します。必要に応じて、生成されたdllを保存して、後で使用することもできます。

これは、たとえば、.NETでシリアライザーアセンブリが生成される方法です。シリアル化されるタイプが検査され、カスタムシリアライザークラスがそのタイプ専用に生成されるため、シリアル化は実行時のリフレクションに依存する必要がありません。

于 2012-09-14T15:35:43.730 に答える