C# 将通用列表转换为特定类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12426426/
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
Convert a Generic List to specific type
提问by Ramesh Durai
I have a List which contains 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 the testDatato the type List<TestClass>?
如何转换testData为类型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 don't want to mention the column names, so that I can use this code irrespective of class changes.
我不想提及列名,这样我就可以使用此代码而不管类发生了怎样的变化。
I also have a IEnumerable<Dictionary<string, object>>which has the data.
我也有一个IEnumerable<Dictionary<string, object>>有数据的。
采纳答案by lc.
You have to explicitly create the TestClass objects, and moreover cast the outer objects to List<object>and the inner objects to strings.
您必须显式创建 TestClass 对象,而且将外部对象转换List<object>为字符串,将内部对象转换为字符串。
testData.Cast<List<object>>().Select(x => new TestClass() {AAA = (string)x[0], BBB = (string)x[1], CCC = (string)x[2]}).ToList()
You could also create a constructor in TestClass that takes List<object>and does the dirty work for you:
您还可以在 TestClass 中创建一个构造函数,该构造函数List<object>为您完成繁琐的工作:
public TestClass(List<object> l)
{
this.AAA = (string)l[0];
//...
}
Then:
然后:
testData.Cast<List<object>>().Select(x => new TestClass(x)).ToList()
回答by KeithS
Linq is your friend:
Linq 是你的朋友:
var testList = testData
.OfType<List<object>>()
.Select(d=> new TestClass
{
AAA = d[0].ToString(),
BBB = d[1].ToString(),
CCC = d[2].ToString()})
.ToList();
EDIT:For the IEnumerable<Dictionary<string,object>>, and without hard-coding field names in the Linq statement, I would simply pass each Dictionary to the constructor of the object to be instantiated, and have the object try to hydrate itself using the field names it knows about:
编辑:对于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;}
}
The constructor can use a reflective loop to get its type's list of fields, then get those KVPs out of the Dictionary and set them to the current instance. That would make it slower, but the code would be more compact which might be a concern if TestClass actually has a dozen fields instead of three. The basic idea remains unchanged; give the data needed to hydrate a TestClass to the TestClass, in the form you have it in, and let the class constructor figure out what to do with it. Understand that this WILL throw an exception on the first error creating any of the TestClass objects.
构造函数可以使用反射循环来获取其类型的字段列表,然后从字典中获取这些 KVP 并将它们设置为当前实例。这会使它变慢,但代码会更紧凑,如果 TestClass 实际上有十几个字段而不是三个,这可能是一个问题。基本思想不变;以您所拥有的形式将将 TestClass 水合到 TestClass 所需的数据提供给它,然后让类构造函数弄清楚如何处理它。了解这将在创建任何 TestClass 对象的第一个错误时引发异常。
回答by dasblinkenlight
You can do it like this:
你可以这样做:
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();

