8

いくつかの値を含むリストがあります。

例:

List<object> testData = new List <object>();
testData.Add(new List<object> { "aaa", "bbb", "ccc" });
testData.Add(new List<object> { "ddd", "eee", "fff" });
testData.Add(new List<object> { "ggg", "hhh", "iii" });

そして、私は次のようなクラスを持っています

class TestClass
{
    public string AAA {get;set;}
    public string BBB {get;set;}
    public string CCC {get;set;}
}

testDataを型に変換する方法はList<TestClass>?

これ以外に変換する方法はありますか?

testData.Select(x => new TestClass()
{
   AAA = (string)x[0],
   BBB = (string)x[1],
   CCC = (string)x[2]
}).ToList();

クラスの変更に関係なくこのコードを使用できるように、列名については言及しません。

IEnumerable<Dictionary<string, object>>はデータを持っている も持っています。

4

3 に答える 3

8

TestClass オブジェクトを明示的に作成し、さらに外側のオブジェクトを文字列にキャストしList<object>、内側のオブジェクトを文字列にキャストする必要があります。

testData.Cast<List<object>>().Select(x => new TestClass() {AAA = (string)x[0], BBB = (string)x[1], CCC = (string)x[2]}).ToList()

TestClass でコンストラクターを作成List<object>して、ダーティな作業を実行することもできます。

public TestClass(List<object> l)
{
    this.AAA = (string)l[0];
    //...
}

それで:

testData.Cast<List<object>>().Select(x => new TestClass(x)).ToList()
于 2012-09-14T14:23:11.347 に答える
7

次のように実行できます。

var res = testData
    .Cast<List<object>>() // Cast objects inside the outer List<object>
    .Select(list => new TestClass {
        AAA = (string)list[0]
    ,   BBB = (string)list[1]
    ,   CCC = (string)list[2]
    }).ToList();
于 2012-09-14T14:24:31.890 に答える
5

Linq はあなたの友達です:

var testList = testData
                  .OfType<List<object>>()
                  .Select(d=> new TestClass
                                  {
                                     AAA = d[0].ToString(), 
                                     BBB = d[1].ToString(), 
                                     CCC = d[2].ToString()})
                  .ToList();

編集:の場合IEnumerable<Dictionary<string,object>>、Linq ステートメントでフィールド名をハードコーディングせずに、インスタンス化するオブジェクトのコンストラクターに各 Dictionary を渡すだけで、オブジェクトが知っているフィールド名を使用して自分自身をハイドレートしようとします。

var testList = testData
                  .OfType<Dictionary<string,object>>()
                  .Select(d=> new TestClass(d))
                  .ToList();

...

class TestClass
{
    public TestClass(Dictionary<string,object> data)
    {
        if(!data.ContainsKey("AAA")) 
           throw new ArgumentException("Key for field AAA does not exist.");
        AAA = data["AAA"].ToString();

        if(!data.ContainsKey("BBB")) 
           throw new ArgumentException("Key for field BBB does not exist.");
        BBB = data["BBB"].ToString();

        if(!data.ContainsKey("CCC")) 
           throw new ArgumentException("Key for field CCC does not exist.");
        CCC = data["CCC"].ToString();
    }

    public string AAA {get;set;}
    public string BBB {get;set;}
    public string CCC {get;set;}
}

コンストラクターは、反射ループを使用してその型のフィールドのリストを取得し、それらの KVP を Dictionary から取得して、現在のインスタンスに設定できます。これにより速度は遅くなりますが、コードはよりコンパクトになり、TestClass に実際に 3 つではなく 12 個のフィールドがある場合に問題になる可能性があります。基本的な考え方は変わりません。TestClass をハイドレートするために必要なデータを TestClass に渡して、それを持っている形式で提供し、クラス コンストラクターにそれをどうするかを理解させます。これは、TestClass オブジェクトを作成する最初のエラーで例外をスローすることを理解してください。

于 2012-09-14T14:24:08.340 に答える