为类的每个属性添加其他属性

时间:2011-11-30 19:34:05

标签: c# .net c#-4.0 attributes

假设我有一个包含任意类型属性的类

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不是我关注的问题;而我应该如何设置此警告?我希望能够做到这样的事情:

对于类中的每个属性,添加一个'Warning'和'Error'属性,以便我可以做..

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

这样做的最佳方法是什么?如果我可以为类的每个属性添加一个自定义属性,这将添加这些附加属性并允许我以清晰的方式访问它们,这将是很好的。

我见过将Dictionary添加到父类(Test)的解决方案,然后传入与属性名称匹配的字符串,或者使用反射获取属性名称并将其传入,但我更喜欢更清洁的东西。

4 个答案:

答案 0 :(得分:9)

您可以向属性添加所需的自定义属性,然后在对象上使用扩展方法来访问这些属性。

这样的事情应该有效

首先,您需要创建属性类

[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"); 来创建自定义泛型类型来处理该属性设置。

这样的东西
{{1}}

使用

{{1}}

答案 1 :(得分:2)

如果你可以使用方法而不是属性,那么你可以为对象创建一个扩展 - 但是对于某些类来说,很难缩小它的用途。

类似的东西:

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

public static String GetWarning(this object target)
{
}

当然在对象的状态下很难保持这样的警告,但是你可以使用一些字典等。

答案 2 :(得分:2)

我建议不要尝试对属性进行属性,而是建议将一组错误/警告属性添加到业务对象继承的基类中。

这样,您可以提供更详细的信息,您可以在向用户显示这些信息时删除它们,如果您通过“电汇”(Web服务,wcf服务)发送数据,则会出现错误可以与您的对象一起旅行,而不需要特殊处理来发送属性。

答案 3 :(得分:1)

首先,属性无法修改它们所放置的对象。除非你把它们与AOP结合起来。如果类没有被密封,我建议通过继承它来在类周围使用包装类。如果它们是密封的,那么你将不得不编写一个实际的包装类,将所有操作(除了你添加的操作)传递给私有字段,该字段是你的包装类的实例。

编辑: 为了便于使用,建议的扩展方法可能是最好的解决方案。