C#属性:一个属性统治所有属性

本文关键字:属性 一个 | 更新日期: 2023-09-27 18:21:09

是否可以在不使用反射的情况下为属性分配属性并使用它来分配其他属性?

代码:

public class CashierOut : BaseActivity
{
    [Description("Flag indicates whether break to execution.")]
    [DefaultValue(false)]
    [MyCustomAttribute(ParameterGroups.Extended)]
    public bool CancelExecution { get; set; }
    [Description("Flag indicates whether allow exit before declation.")]
    [DefaultValue(true)]
    [MyCustomAttribute(ParameterGroups.Extended)]
    [DisplayName("Exit before declaration?")]
    public bool AllowExitBeforeDeclare { get; set; }
}

我想做这样的事情:

public class CashierOut : BaseActivity
{
    [MyResourceCustom("CashierOut.CancelExecution")]
    public bool CancelExecution { get; set; }
    [MyResourceCustom("CashierOut.AllowExitBeforeDeclare")]
    public bool AllowExitBeforeDeclare { get; set; }
}
public sealed class MyResourceCustom : Attribute
{
    public string ResourcePath { get; private set; }
    public ParameterGroupAttribute(string resourcePath)
    {
        ResourcePath = resourcePath;
        // Get attributes attributes value from external resource using the path.
    }
}

C#属性:一个属性统治所有属性

属性只需将元数据添加到定义它们的成员中——它们自己什么都不做。

您必须使用反射才能根据属性值产生一些行为。

这就是所有属性的工作方式——一些工具知道一些属性(如编译器和ConditionalAttribute),但这仍然是通过反射来完成的。

研究面向方面编程。您可以使用postsharp等工具在编译或运行时修改代码。

您可以向MyResourceCustom添加一个成员,该成员将Description、DefaultValue和MyCustomAttribute封装在一个不可变的实例中(如果每个人都可以相同,甚至可以是静态全局)。

public class MyResourceCustom : Attribute {
  public MyResourceCustomDescriptor Descriptor { get; private set; }
  public MyResourceCustom(MyResourceCustomDescriptor descriptor)
  : base() {
    Descriptor = descriptor;
  }
public class MyResourceCustomDescriptor {
  public string          Description    { get; private set; }
  public bool            DefaultValue   { get; private set; }
  public ParameterGroups ParameterGroup { get; private set; }
  public MyResourceCustomDescriptor(string path) {
    // read from path
  }
}
public class MyAdvancedResouceCustomDescriptor : MyResourceCustomDescriptor {
  public string DisplayName { get; private set; }
  // etc...
}

获取属性时,可以获取其Descriptor属性并读取值。

作为旁注,您应该将其命名为IsDefaultValue