Атрибуты и параметры массива, совместимые с CLS

#c# #attributes #cls-compliant

#c# #атрибуты #совместимые с cls

Вопрос:

Я создал атрибут, который принимает массив (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, но на данный момент я не могу этого сделать.

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

Ответ №1:

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

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

Комментарии:

1. Arg, победи меня! Но почему CLS жалуется на класс внутренних атрибутов?

2. Да, Option это перечисление, и сайт вызова будет использовать не более трех или четырех вариантов, так что это отличное решение. Tnx, у меня было ощущение, что я упускаю из виду что-то очевидное 🙂

3. @leppie, это не жалобы на определение атрибута (это так, если он общедоступен), это жалобы на общедоступные сайты вызовов.

Ответ №2:

«Массивы в качестве аргументов атрибута не совместимы с 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 предназначен для проверки только на возможных внешних элементах (общедоступных / защищенных).

Комментарии:

1. Он не жалуется на определение атрибута (это так, если он общедоступен), он жалуется на общедоступные сайты вызовов.