2012-12-04 34 views
3

我有一個函數,通過選定的字段過濾特定類的對象。我現在這樣做的方式是將字段的字符串作爲參數傳遞給函數。理想情況下,我希望能夠使用此字符串來選擇對象中的字段,類似於字典(例如,此功能存在於JavaScript中)。按名稱選擇一個類字段,就像它是一本字典一樣?

所以我具備的功能(砍倒在相關位)位置:

private List<HangingArtBundle> ConstrainBundlesBy(List<HangingArtBundle> bundles, string valueString, string constraint) 
{ 
    List<HangingArtBundle> retBundles = new List<HangingArtBundle>(); 
    List<string> values = new List<string>(valueString.Split(new char[] { '|' })); 

    foreach (HangingArtBundle bundle in bundles) 
    { 
     if (values.Contains(ConstrainedField(constraint, bundle))) 
     { 
      retBundles.Add(bundle); 
     } 
    } 

    return retBundles; 
} 

我希望能夠用的東西來代替ConstrainedField(constraint, bundle)部分像bundle[constraint],其中constraint是一個字段的名稱類別HangingArtBundle。相反,我不得不使用下面這個函數,這就需要我手動添加字段名需要:

private string ConstrainedField(string field, HangingArtBundle bundle) 
{ 
    if (field.Equals("Category")) 
    { 
     return bundle.Category; 
    } 
    else if (field.Equals("AUToolTab")) 
    { 
     return bundle.AUToolTab; 
    } 
    else 
    { 
     return ""; 
    } 
} 

如果有幫助可言,這裏是類(本質上只是一個結構):

public class HangingArtBundle 
{ 
    public string CP { get; set; } 
    public string Title { get; set; } 
    public string Category { get; set; } 
    public string AUToolTab { get; set; } 
    public List<HangingArtEntry> Art { get; set; } 
} 

這可能在C#中以優雅的方式做到嗎?

+0

參考在這裏可能是一個明顯的答案,但我更關心這個代碼實際上試圖完成什麼。它看起來並不像你真的需要反射或元編程結構。看起來更像是你試圖過濾屬性具有特定價值的對象集合。如果是這樣的話,我的建議是將這個重構成更清晰的代碼,而不是試圖用反射來取代一些奇怪的代碼。只是我的兩美分 – Didaxis

+0

@ErOx嗯,我有這些HangingArtBundles的緩存,可以通過一個API訪問,它具有諸如「GetAllHangingArtByCategory」和「GetAllHangingArtByAUToolTab」之類的方法,除了過濾字段之外,它們的主體是相同的。所以我寫了一個GetAllHangingArtByX函數的通用版本,這引起了我的這個問題。我想一個更清晰的解決方法是更改​​我的數據存儲的格式,但是我選擇了這種類似於結構的設置來最乾淨地模擬嵌套的JSON結構 - 這些結果最終將被序列化爲。 –

回答

5

您可以使用System.Reflection

private string GetField(HangingArtBundle hab, string property) 
{ 
    return (string)hab.GetType().GetProperty(property).GetValue(hab, null); 
} 

enter image description here

或者可能是擴展方法,使生活更容易一點:

public static class Extensions 
    { 
     public static string GetField(this HangingArtBundle hab, string property) 
     { 
      if (hab.GetType().GetProperties().Any(p => p.Name.Equals(property))) 
      { 
       return (string)hab.GetType().GetProperty(property).GetValue(hab, null); 
      } 
      return string.Empty; 
     } 
    } 

用法:

string result = bundle.GetField("CP"); 
+0

太好了,謝謝。這正是我所期待的。 –

+1

增加了一個擴展方法的例子,這對你來說更容易。 :) –

相關問題