2017-08-11 121 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) ... 

根本不需要反射,一切都是強類型的。