2012-11-01 65 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; 
}