2009-09-19 117 views
37

假設我有很多對象,並且它們有很多字符串屬性。在C中枚舉對象的屬性(字符串)#

是否有編程方式來通過它們並輸出屬性名及其值?還是必須進行硬編碼?

是否有LINQ方法來查詢對象'string'類型的屬性並輸出它們?

您是否必須硬編碼想要回顯的屬性名稱?

回答

70

使用反射。它遠不及硬編碼的屬性訪問速度快,但它可以滿足你的需求。

以下查詢產生用於對象中的每個串類型屬性匿名類型與名稱和Value屬性「myObject的」:

var stringPropertyNamesAndValues = myObject.GetType() 
    .GetProperties() 
    .Where(pi => pi.PropertyType == typeof(string) && pi.GetGetMethod() != null) 
    .Select(pi => new 
    { 
     Name = pi.Name, 
     Value = pi.GetGetMethod().Invoke(myObject, null) 
    }); 

用法:

foreach (var pair in stringPropertyNamesAndValues) 
{ 
    Console.WriteLine("Name: {0}", pair.Name); 
    Console.WriteLine("Value: {0}", pair.Value); 
} 
+2

相反pi.GetGetMethod()調用的(myObject的,NULL)我寧願使用pi.GetValue(myObject的,空) - 簡單的閱讀。 – Sam

3

可以使用反射來做這個... 。在 CodeGuru有一篇不錯的文章,但這可能比您要找的更多......您可以從中學習,然後將其修剪成您的需求。

-2

這樣的事情呢?

public string Prop1 
{ 
    get { return dic["Prop1"]; } 
    set { dic["Prop1"] = value; } 
} 

public string Prop2 
{ 
    get { return dic["Prop2"]; } 
    set { dic["Prop2"] = value; } 
} 

private Dictionary<string, string> dic = new Dictionary<string, string>(); 
public IEnumerable<KeyValuePair<string, string>> AllProps 
{ 
    get { return dic.GetEnumerator(); } 
} 
11

您可以通過使用GetProperties方法獲得某個類型的所有屬性。然後,您可以使用LINQ Where擴展方法過濾此列表。最後,您可以使用LINQ Select擴展方法或像ToDictionary這樣的便捷快捷方式來投影屬性。

如果你想限制枚舉類型具有的String您可以使用此代碼屬性:

IDictionary<String, String> = myObject.GetType() 
    .GetProperties() 
    .Where(p => p.CanRead && p.PropertyType == typeof(String)) 
    .ToDictionary(p => p.Name, p => (String) p.GetValue(myObject, null)); 

這將創建一個屬性名稱映射到屬性值的字典。由於屬性類型限制爲String,因此將屬性值轉換爲String並且返回類型爲IDictionary<String, String>是安全的。

如果你不是希望所有的屬性,你可以做這樣的:

IDictionary<String, Object> = myObject.GetType() 
    .GetProperties() 
    .Where(p => p.CanRead) 
    .ToDictionary(p => p.Name, p => p.GetValue(myObject, null)); 
3

如果你的目標很簡單,就是輸出存儲在使用人類可讀的格式對象的屬性數據,我更喜歡簡單的序列化將對象轉換爲JSON格式。

using System.Web.Script.Serialization; 
//... 

string output = new JavaScriptSerializer().Serialize(myObject);