Convert a general list to a specific type

I have a list containing some values.

Example:

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

And I have a class like

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

How to convert testDatato type List<TestClass>?

Is there a way to convert other than this?

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

I do not want to mention column names, so I can use this code regardless of class changes.

I also have IEnumerable<Dictionary<string, object>>one that has data.

+5
source share
3 answers

You need to explicitly create TestClass objects and, in addition, include external objects in List<object>and internal objects in strings.

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

You can also create a constructor in TestClass that accepts List<object>, and the dirty work for you:

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

Then:

testData.Cast<List<object>>().Select(x => new TestClass(x)).ToList()
+7
source

:

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();
+7

- :

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

EDIT:. IEnumerable<Dictionary<string,object>> Linq , , , , :

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

The constructor can use the reflective loop to get its list of field types, then get these KVPs from the dictionary and set them to the current instance. That would make it slower, but the code would be more compact, which could be troubling if TestClass actually has a dozen fields instead of three. The basic idea remains unchanged; provide the data necessary for hydrating TestClass to TestClass, in the form in which you have it, and let the class constructor understand what to do with it. Understand that this WILL throws an exception on the first error that creates any TestClass object.

+5
source

All Articles