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-совместимость, но сейчас я не могу этого сделать.
Есть ли какой-то другой подход к созданию атрибута, который все еще будет делать то же самое, но избавится от предупреждений?
2 ответа
Два варианта:
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]
enum, и пусть вызывающий соединяет их:
[MyTest(Option.One | Option.Two)]
с:
[Flags]
public enum Option {
None = 0,
One = 1,
Two = 2,
Three = 4,
Four = 8,
...
}
"Массивы как аргументы атрибута не совместимы с 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 предназначен только для проверки на возможных внешних участниках (общедоступных / защищенных).