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

use*_*225 14 .net c# attributes c#-4.0

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

public class Test
{
public string A {get;set;}
public object B {get;set;}
public int C {get;set;}
public CustomClass D {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

我希望这个类中的所有对象都有"错误"和"警告"的概念.例如,基于另一个类中的某些条件,我可能想要在属性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;
Run Code Online (Sandbox Code Playgroud)

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

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

msa*_*het 10

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

这样的事情应该有效

首先,您需要创建属性类

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

   public WarningAttribute(string warning)
   {
      this.Warning = warning;
   }    
}
Run Code Online (Sandbox Code Playgroud)

更多阅读在这里

这样使用它

[WarningAttribute("Warning String")]
public string A {get;set;}
Run Code Online (Sandbox Code Playgroud)

然后像MSDN文章那样访问它

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;
            }
        } 
}
Run Code Online (Sandbox Code Playgroud)

然后,如果您有想要访问警告的项目,则只需致电即可

test.A.Warning;
Run Code Online (Sandbox Code Playgroud)

如果你想设置警告字符串,你可以更干净地实现某种类型的setter.可能通过设置辅助对象或属性类型.


另一种方法是使用string,而不是仅仅使用,object您可以创建一个自定义泛型类型来处理该属性设置.

就像是

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;
   }
}
Run Code Online (Sandbox Code Playgroud)

用得像

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