2012-11-01 33 views
2

我一直在读了老问题问ANS搜索MSDN帮助,但我真的不能明白的PropertyInfo是什么,具体涉及通过一个数组列表Foreach更改属性。什么是PropertyInfo?

c# foreach (property in object)... Is there a simple way of doing this?)循环的问题

我做了一个简单的类

public MyClass 
{ 
public double myProperty; // etc 
} 

然后我将类对象添加到列表中。我想遍历列表,只改变每个对象的属性

foreach (MyClass i in MyClassList) 
{ 
foreach (double myProperty in i.GetType().GetProperties()) 
{ 
// do something 
} 


} 

但我得到一个错误。在上面的链接问题中,它表示使用PropertyInfo而不是'double'。什么是PropertyInfo应该取代myProperry的“双”,它代表什么?

+0

'myProperty'实际上并不是一个属性......它是一个*字段*;它**不会在'GetProperties' –

回答

1

PropertyInfo仅仅代表财产被定义的事实那种类型;它不是每个对象 - 它是用于类型的。您不需要任何实例即可获得PropertyInfo

然而,首先注意的是myProperty目前还没有一个属性:我们进行了修复第一:

public MyClass 
{ 
    public double MyProperty {get;set;} 
} 

现在我们可以了解该属性,要么通过询问“它拥有的所有属性”,

PropertyInfo prop = typeof(MyClass).GetProperty("MyProperty"); 
:即

PropertyInfo[] props = typeof(MyClass).GetProperties(); 

或个人财产,也许是从配置在运行时获得的名称

您可以检查PropertyInfo的名称,类型,属性等 - 对于库代码非常有用。然而,在常规代码最简单的方法就是使用静态C#:

foreach(MyClass obj in MyClassList) { 
    obj.MyProperty = 123.45; 
} 

如果你需要通过反射做到这一点,那么你可以使用SetValue

foreach(MyClass obj in MyClassList) { 
    prop.SetValue(obj, 123.45, null); 
}  

然而,反射除非你做得更好,否则会比较慢。例如,针对“我将在运行时知道名称”的另一种替代方案是FastMember;那么你可以这样做:

var accessor = TypeAccessor.Create(typeof(MyClass)); 
string propName = "MyProperty"; 
object value = 123.45; 
foreach(MyClass obj in MyClassList) { 
    accessor[obj, propName] = value; 
} 

,这将是比生反射快得多,而在运行时查找属性,名称方面具有更大的灵活性。

+0

感谢marc中显示**。我没有使用get:set作弊。那是个大问题,但我很欣赏这个解释! – AbeeCrombie

1

你可能想这个的一个例子:

foreach (MyClass i in MyClassList) 
{ 
    foreach (var myProperty in i.GetType().GetProperty("myProperty")) 
    { 
     myProperty.SetValue(i, 1.23); 
    } 
} 

这相当于:

foreach (MyClass i in MyClassList) 
{ 
    i.myProperty = 1.23; 
}