2009-07-29 96 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!"); 
    } 
}