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

构造函数可以使用反射循环来获取其类型的字段列表,然后从 Dictionary 中获取这些 KVP 并将它们设置为当前实例。这会使它变慢,但代码会更紧凑,如果 TestClass 实际上有十几个字段而不是三个字段,这可能是一个问题。基本思想不变;以您拥有的形式将 TestClass 所需的数据提供给 TestClass,并让类构造函数弄清楚如何处理它。了解这将在创建任何 TestClass 对象的第一个错误时引发异常。

于 2012-09-14T14:24:08.340 回答