2011-11-30 108 views
11

說我有任何數量的任何類型的添加附加屬性一類的每個屬性

public class Test 
{ 
public string A {get;set;} 
public object B {get;set;} 
public int C {get;set;} 
public CustomClass D {get;set;} 
} 

我想這一切的類中的對象的屬性的類有「錯誤」的概念, 「警告」。例如,根據另一個類中的某些條件,我可能希望對屬性A設置警告,然後在GUI中顯示該信息。 GUI不是我關心的問題;而應該如何設置此警告?我希望能夠做這樣的事情:

爲類中的每個屬性,添加一個「警告」和「錯誤」屬性,這樣我可以做..

Test t = new Test(); 
t.A.Warning = "This is a warning that the GUI will know to display in yellow". 
t.B.Error = null; 

什麼是最好的這樣做的方式?如果我可以爲該類的每個屬性添加一個自定義屬性以添加這些附加屬性並允許我以一種明確的方式訪問它們,那將會很好。

我見過添加一個字典到父類(Test)的解決方案,然後傳入匹配屬性名稱的字符串,或者使用反射來獲取屬性名稱並將其傳入,但我更喜歡清理乾淨的東西。

回答

8

你可以添加自定義屬性您想要屬性,然後在對象上使用擴展方法來訪問這些屬性。

像這樣的東西應該工作

首先你需要創建屬性類

[AttributeUsage(AttributeTargets.All/*, AllowMultiple = true*/)] 
public class WarningAttribute : System.attribute 
{ 
    public readonly string Warning; 

    public WarningAttribute(string warning) 
    { 
     this.Warning = warning; 
    }  
} 

更多的閱讀Here

使用它作爲這樣

[WarningAttribute("Warning String")] 
public string A {get;set;} 

然後訪問如此MSDN Article

public static string Warning(this Object object) 
{ 
    System.Attribute[] attrs = System.Attribute.GetCustomAttributes(object); 

    foreach (System.Attribute attr in attrs) 
     { 
      if (attr is WarningAttrbiute) 
      { 
       return (WarningAttribute)attr.Warning; 
      } 
     } 
} 

然後,如果你有,你要訪問你的警告,一個項目可以簡單地調用

test.A.Warning; 

如果你想設置的警告字符串您可以實現某種二傳手的那更乾淨一點。可能通過設置輔助對象或屬性類型。


的另一種方法做到這一點是不是隻用stringobject你可以創建一個自定義泛型類型來處理該屬性設置。

喜歡的東西

public class ValidationType<T> 
{ 
    public T Value {get; set;} 
    public string Warning {get; set;} 
    public string Error {get; set;} 

    public ValidationType(T value) 
    { 
     Value = value; 
    } 
} 

使用像

var newWarning = new ValidationType<string>("Test Type"); 
newWarning.Warning = "Test STring"; 
Console.WriteLine("newWarning.Value"); 

+0

謝謝你的迴應。我想我會執行這個。我不喜歡使用newWarning.Value來實際訪問字符串屬性,但似乎我將不得不在某處犧牲一些便利。 – user981225

1

首先,屬性不能修改它們放置的對象。除非你將它們與AOP結合起來。如果類沒有被封閉,我會建議在類的周圍使用一個包裝類繼承它。如果它們是密封的,那麼你必須寫一個實際的包裝類,將所有操作(除了添加的操作之外)傳遞給私有字段,該字段是包裝類的實例。

編輯: 爲便於使用,建議的擴展方法aproach可能是最好的解決方案。

2

如果你可以用一種方法而不是屬性來獲得,那麼你可以爲對象創建一個擴展 - 但是這很難縮小它僅僅用於某些類。

喜歡的東西:

public static void Warning(this object target, string message) 
{ 
... 
} 

public static String GetWarning(this object target) 
{ 
} 

當然,這將是很難維持對象的狀態這樣的警告,但你可以使用一些字典等

+0

謝謝你的帖子,但我寧願避免這種解決方案。我希望實際屬性知道它是否有錯誤,而不是父對象必須循環訪問字符串字典(例如)。 – user981225

2

而不是試圖屬性的屬性,我建議將錯誤/警告屬性的集合基類,你的業務對象從中繼承。

這樣,您可以提供更詳細的信息,您可以在它們顯示給用戶時將其刪除,並且,如果您通過「線路」(Web服務,wcf服務)發送數據,則錯誤可以隨您的對象一起傳播,而不需要特殊的處理來發送屬性。