CLS-совместимые атрибуты и параметры массива - PullRequest
6 голосов
/ 31 октября 2011

Я создал атрибут, который принимает массив (params) в своем конструкторе.

internal class MyTestAttribute : Attribute
{
    public MyTestAttribute (params Options[] options)
    {
        ....
    }
}

Option здесь перечисление (с большим количеством значений), поэтому образец сайта вызова будет

[MyTest(Option.One, Option.Three)]
internal void SomeMethod(int param1, long param2)
{
  ....
}

Пока все замечательно, и установка работает, но я получаю " Массивы как аргументы атрибута не совместимы с CLS " на каждом сайте вызова.Теперь я должен признать, что мне не нужно использовать эту сборку где-либо еще, кроме C #, и я не делаю предупреждения как ошибки, но сотни предупреждений раздражают.

Очевидное решениеотключить CLS-совместимость, но на данный момент я не могу этого сделать.

Есть ли какой-то другой подход к созданию атрибута, который все равно будет делать то же самое, но избавится от предупреждений?

Ответы [ 2 ]

12 голосов
/ 31 октября 2011

Два варианта:

1: вместо этого вы можете добавить несколько перегрузок:

private MyTestAttribute(Option[] options) {...}
public MyTestAttribute(Option option0)
          : this(new[] {option0}) {}
public MyTestAttribute(Option option0, Option option1)
          : this(new[] {option0, option1}) {}
public MyTestAttribute(Option option0, Option option1, Option option2)
          : this(new[] {option0, option1, option2}) {}
// add a few more, without going crazy

2: если Options - это перечисление, пометьте перечисление как [Flags] и попросите вызывающего пользователя объединить их:

[MyTest(Option.One | Option.Two)]

с:

[Flags]
public enum Option {
     None = 0,
     One = 1,
     Two = 2,
     Three = 4,
     Four = 8,
     ...
}
4 голосов
/ 31 октября 2011

"Массивы в качестве аргументов атрибута не совместимы с CLS"

Именно то, что написано.

Единственный обходной путь - создание явных параметров, например:

internal class MyTestAttribute : Attribute
{
    public MyTestAttribute(Option o1) : this(new Option[] { o1 }) {}
    public MyTestAttribute(Option o1, Option o2) : 
      this(new Option[] { o1, o2 }) {}

    MyTestAttribute (Options[] options)
    {
        ....
    }
}

Примечание: Забавно, что CLS соблюдается, учитывая, что класс атрибута является внутренним. AFAIK, CLS предназначен только для проверки на возможных внешних участниках (общедоступных / защищенных).

...