#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. Он не жалуется на определение атрибута (это так, если он общедоступен), он жалуется на общедоступные сайты вызовов.