Подтвердить что ты не робот

Как передать объекты в конструктор атрибутов

Я пытаюсь передать объекты в конструктор атрибутов следующим образом:

[PropertyValidation(new NullOrEmptyValidatorScheme())]
public string Name { get; private set; }

С помощью этого конструктора атрибутов:

 public PropertyValidationAttribute(IValidatorScheme validator) {
      this._ValidatorScheme = validator;
    }

Код не будет компилироваться. Как передать объект в атрибут, как указано выше?

EDIT: Да NullOrEmptyValidatorScheme реализует метод IValidatorScheme.

Ошибка: ошибка CS0182: Аргумент атрибута должен быть константным выражением, выражением типаof или выражением для создания массива типа атрибута.

4b9b3361

Ответ 1

Значения в атрибутах ограничены простыми типами; например, базовые константы (включая строки) и typeof... вы не можете использовать new или другой более сложный код. Вкратце; вы не можете этого сделать. Вы можете указать тип , хотя:

[PropertyValidation(typeof(NullOrEmptyValidatorScheme)]

то есть. PropertyValidation ctor принимает Type и использует Activator.CreateInstance внутри кода для создания объекта. Обратите внимание: в идеале вы должны просто сохранить строку внутри (AssemblyQualifiedName).

Из ECMA 334v4:

§24.1.3 Типы параметров атрибутов

Типы позиционных и названных параметры для класса атрибута: ограниченный параметром атрибута типы, которые:

  • Один из следующих типов: bool, byte, char, double, float, int, long, short, string.
  • Тип object.
  • Тип System.Type.
  • Тип перечисления, если он имеет общедоступную доступность и типы, в которых он вложен (если есть) также имеют общедоступную доступность.
  • Одномерные массивы выше типы.

и

§24.2. Спецификация атрибута

...

Выражение E является attribute-argument-expression, если все из следующих утверждений:

  • Тип E - это атрибут тип параметра (§24.1.3).
  • Во время компиляции значение E может быть разрешено к одному из следующих:
    • Постоянное значение.
    • Тип-выражение (§14.5.11), определяющее не общий тип, закрытый построенный тип (§25.5.2) или несвязанный общий тип (§25.5).
    • Одномерный массив атрибут-аргументов-выражений.

Ответ 2

Как отмечалось в предыдущих плакатах, типы, используемые в аргументах атрибутов, сильно ограничены (понятно, потому что их значения должны быть сериализованы непосредственно в блоке метаданных сборки).

Тем не менее, вы можете создать решение, которое использует typeofs, так как те могут использоваться.

Например:

[PropertyValidation(typeof(NullOrEmptyValidatorScheme))]
public string Name { get; private set; }

Этот синтаксис совершенно легален. Код, который читает ваши атрибуты, вы должны получить тип валидатора, создать новый экземпляр валидатора (он может даже поддерживать кэш валидаторов с ключами типов валикаторов, если это необходимо - это довольно распространенный метод), а затем вызывать его.

Ответ 3

Также... (я думаю, что это ошибка Microsoft)

Вы не можете поместить значение по умолчанию в "null", но стандартное по умолчанию значение по умолчанию - "ok" ( "false", "7", "Test" ).

Пример NExt даст вам следующую ошибку: Аргумент атрибута должен быть константным выражением, выражением typeof или выражением создания массива типа параметра атрибута
в файле:...\CSC

public class SampleAttribute : Attribute
{
    private string _test;
    public SampleAttribute(string test = null)
    {
        _test = test;
    }
}

[Sample]
public class Toto
{

}