2009-07-29 46 views
81

我有這樣的:如何在C#中訪問匿名類型的屬性?

List<object> nodes = new List<object>(); 

nodes.Add(
new { 
    Checked  = false, 
    depth  = 1, 
    id   = "div_" + d.Id 
}); 

...我想知道如果我可以再搶匿名對象的「選中」屬性。我不確定這是否可能。試圖這樣做:

if (nodes.Any(n => n["Checked"] == false)) ...但它不工作。

感謝

回答

52

如果你想匿名類型的強類型列表中,你需要做出的排行榜匿名類型了。最簡單的方法是將諸如數組之類的序列投影到列表中,例如,

var nodes = (new[] { new { Checked = false, /* etc */ } }).ToList(); 

然後你就可以訪問它,如:

nodes.Any(n => n.Checked); 

,因爲這樣的編譯工作,以下則還應該工作,一旦你已經創建的列表,因爲匿名類型具有相同的結構,所以它們也是相同的類型。我沒有編譯器來手來驗證這一點,但。

nodes.Add(new { Checked = false, /* etc */ }); 
200

如果要將對象存儲爲object類型,則需要使用反射。任何對象類型(匿名或其他)都是如此。在對象O,你可以得到它的類型:

Type t = o.GetType(); 

然後從你看到了一個屬性:

PropertyInfo p = t.GetProperty("Foo"); 

然後從,你可以得到一個值:

object v = p.GetValue(o, null); 

對於C#4的更新,此答案早已過期:

dynamic d = o; 
object v = d.Foo; 

而現在另一種選擇在C#6:

object v = o?.GetType().GetProperty("Foo")?.GetValue(o, null); 

注意,通過使用?.我們導致生成的v是在三種不同的情況null

  1. onull,所以在所有
  2. o沒有對象非null但沒有一個屬性Foo
  3. o有一個屬性Foo,但其真正的價值恰好是null

因此,這不等同於前面的例子,但如果您想要對待所有三種情況相同,則可能有意義。

+4

使用了前所未有的動態到目前爲止,漂亮的更新.NET 4.0 – Alan 2012-11-09 17:10:31

+1

WOOW,好爲C#4 = d這在c#4解決方案中爲我工作 – ch2o 2013-01-16 16:24:08

12

您可以使用反射來遍歷匿名類型的屬性;看看是否有一個「檢查」屬性,如果有,然後得到它的價值。

看到這個博客帖子: http://blogs.msdn.com/wriju/archive/2007/10/26/c-3-0-anonymous-type-and-net-reflection-hand-in-hand.aspx

因此,像:

foreach(object o in nodes) 
{ 
    Type t = o.GetType(); 

    PropertyInfo[] pi = t.GetProperties(); 

    foreach (PropertyInfo p in pi) 
    { 
     if (p.Name=="Checked" && !(bool)p.GetValue(o)) 
      Console.WriteLine("awesome!"); 
    } 
}