Атрибуты C #: один атрибут, чтобы управлять ими всеми? - PullRequest
6 голосов
/ 24 января 2012

Можно ли назначить атрибут для свойства и использовать его для назначения других атрибутов - без использования отражения?

Код:

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.
    }
}

Ответы [ 3 ]

6 голосов
/ 24 января 2012

Атрибуты просто добавляют метаданные к элементам, для которых они определены - сами по себе они ничего не делают.

Вам нужно будет использовать отражение, чтобы создать поведение, зависящее от значений атрибута.

Так работают все атрибуты - некоторые инструменты знают о некоторых атрибутах (например, компилятор и ConditionalAttribute), но это все еще делается с помощью отражения.

2 голосов
/ 24 января 2012

Изучите аспектно-ориентированное программирование. Вы можете использовать такие инструменты, как postsharp , чтобы изменить код во время компиляции или во время выполнения.

1 голос
/ 24 января 2012

Вы можете добавить члена к 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...