2017-08-11 89 views
3

我有一些示例代码看起来像这样:如何迭代匿名对象列表?

var items = new List<object>(); 

var testObjectOne = new 
{ 
    Valueone = "test1", 
    ValueTwo = "test2", 
    ValueThree = "test3" 
}; 
var testObjectTwo = new 
{ 
    Valueone = "test1", 
    ValueTwo = "test2", 
    ValueThree = "test3" 
}; 
items.Add(testObjectOne); 
items.Add(testObjectTwo); 

foreach (var obj in items) 
{ 
    var val = obj.Valueone; 
} 

但我不能访问Valueone并且得到错误:对象”不包含定义‘Valueone’,没有扩展方法‘Valueone’接受可以找到类型'对象'的第一个参数(您是否缺少使用指令或程序集引用?)

问题:如何遍历此列表并访问ValueOne,例如?任何帮助或输入的高度赞赏,感谢

+1

var items =(new [] {testObjectOne})。ToList()'。或者'新列表()'。或者一个辅助方法来推断列表类型而不实际添加对象。或者使用元组。或者,我个人最喜欢的选择,不要懒惰,只要申报一个班级。 –

+0

这听起来像是一个xy问题。你为什么不为你的测试对象创建一个专用类型,并将这些实例放在一个'List '中? –

+0

列表中的项目类型为'object',它不包含'ValueOne'的定义。你可以做一些像'var items = Enumerable.Empty ().Select(o => {/ *匿名定义* /})。ToList()'。 – dcg

回答

5

你可以使用反射来获取匿名类型的属性:

var items = new List<object>(); 

var testObjectOne = new 
{ 
    Valueone = "test1", 
    ValueTwo = "test2", 
    ValueThree = "test3" 
    }; 
var testObjectTwo = new 
{ 
    Valueone = "test1", 
    ValueTwo = "test2", 
    ValueThree = "test3" 
}; 
items.Add(testObjectOne); 
items.Add(testObjectTwo); 

foreach (var obj in items) 
{ 
    var val = obj.GetType() 
     .GetProperty("Valueone") 
     .GetValue(obj); 
} 
+0

谢谢!这解决了它 – mattias

3

你必须使用反射,如果你不将它转换回原来的对象

System.Reflection.PropertyInfo pi = item.GetType().GetProperty("Valueone"); 
string Valueone = (string)(pi.GetValue(item, null)); 

或者你也可以改变对象动态

var items = new List<dynamic>(); 

var testObjectOne = new 
{ 
    Valueone = "test1", 
    ValueTwo = "test2", 
    ValueThree = "test3" 
}; 
items.Add(testObjectOne); 
items.Add(testObjectTwo); 

foreach (var obj in items) 
{ 
    var val = obj.Valueone; 
} 
+0

谢谢,我将实际改变为动态! – mattias

3

另一个这样无反射lution将创建一个类似的匿名对象的列表:

var items = Enumerable.Empty<object>().Select(o=>{ 
       Valueone = "test1", 
       ValueTwo = "test2", 
       ValueThree = "test3" 
      }).ToList(); 

编辑:将对象添加到列表中

items.Add(new { 
    Valueone = "Value one", 
    ValueTwo = "Value two", 
    ValueThree = "Value three" 
}); 

那么for内声明var val = obj.Valueone将编译成功。

+0

这只会创建一个匿名类型的空列表,无法对其进行迭代。 – HimBromBeere

+0

@HimBromBeere在行动。我只指出了一种创建匿名对象列表的方法。我编辑了我的答案以显示如何将项目添加到列表中。谢谢。 – dcg

3

为什么不创建一个类来表示这些对象?=!这将使你的代码更加牢固可避免slow/costly reflectionunsafe /bad practice dynamic杂技:

public class TempObject 
{ 
    public string Valueone { get; set; } 
    public string ValueTwo { get; set; } 
    public string ValueThree { get; set; } 
} 

var items = new List<TempObject>(); 

var testObjectOne = new TempObject 
{ 
    Valueone = "test1", 
    ValueTwo = "test2", 
    ValueThree = "test3" 
}; 

items.Add(testObjectOne); 

foreach (var obj in items) 
{ 
    var val = obj.Valueone; 
} 
2

只需创建您的列表,匿名类型还,还不如`名单:

var list = new[] { new 
     { 
      Valueone = "test1", 
      ValueTwo = "test2", 
      ValueThree = "test3" 
     }, 
     new 
     { 
      Valueone = "test1", 
      ValueTwo = "test2", 
      ValueThree = "test3" 
     } 
    }.ToList(); 

您甚至可以添加新元素列表:

list.Add(new { 
    Valueone = "test1", 
    ValueTwo = "test2", 
    ValueThree = "test3" 
}); 

现在你可以使用var轻松地重复该数组:

foreach(var e in list) ... 

根本不需要反射,一切都是强类型的。