Я могу инициализировать атрибут C# с массивом или другим переменным количеством аргументов?

97
задан Crono 12 December 2018 в 21:41
поделиться

6 ответов

Атрибуты возьмут массив. Хотя при управлении атрибутом можно также использовать params вместо этого (который более хорош потребителям, IMO):

class MyCustomAttribute : Attribute {
    public int[] Values { get; set; }

    public MyCustomAttribute(params int[] values) {
       this.Values = values;
    }
}

[MyCustomAttribute(3, 4, 5)]
class MyClass { }

Ваш синтаксис для создания массива просто, оказывается, прочь:

class MyCustomAttribute : Attribute {
    public int[] Values { get; set; }

    public MyCustomAttribute(int[] values) {
        this.Values = values;
    }
}

[MyCustomAttribute(new int[] { 3, 4, 5 })]
class MyClass { }
171
ответ дан Mark Brackett 24 November 2019 в 05:23
поделиться

Можно сделать это, но это не CLS-совместимо:

[assembly: CLSCompliant(true)]

class Foo : Attribute
{
    public Foo(string[] vals) { }
}
[Foo(new string[] {"abc","def"})]
static void Bar() {}

Шоу:

Warning 1   Arrays as attribute arguments is not CLS-compliant

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

[Foo("abc"), Foo("def")]

Однако это не будет работать с TypeDescriptor / PropertyDescriptor, где только единственный экземпляр любого атрибута поддерживается (или первые или последние победы, я не могу вспомнить который).

31
ответ дан Ben Collins 24 November 2019 в 05:23
поделиться

Попытайтесь объявить конструктора как это:

public class MyCustomAttribute : Attribute
{
    public MyCustomAttribute(params int[] t)
    {
    }
}

Тогда можно использовать его как:

[MyCustomAttribute(3, 4, 5)]

22
ответ дан Scott Dorman 24 November 2019 в 05:23
поделиться

Это должно быть хорошо. От спецификации разделите 17.2:

выражение E выражение аргумента атрибута , если все следующие утверждения верны:

  • тип E является типом параметра атрибута (В§17.1.3).
  • Во время компиляции, значение E может быть разрешено к одному из следующего:
    • постоянная величина А.
    • Система А. Текстовый объект.
    • А одномерный массив выражения аргумента атрибута .

Вот пример:

using System;

[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)]
public class SampleAttribute : Attribute
{
    public SampleAttribute(int[] foo)
    {
    }
}

[Sample(new int[]{1, 3, 5})]
class Test
{
}
12
ответ дан Jon Skeet 24 November 2019 в 05:23
поделиться

Да, но необходимо инициализировать массив, в котором Вы являетесь передающими. Вот пример от теста строки в наших модульных тестах, который тестирует переменное количество параметров командной строки;

[Row( new[] { "-l", "/port:13102", "-lfsw" } )]
public void MyTest( string[] args ) { //... }
4
ответ дан Rob Prouse 24 November 2019 в 05:23
поделиться

Можно сделать это. Другой пример мог быть:

class MyAttribute: Attribute
{
    public MyAttribute(params object[] args)
    {
    }
}

[MyAttribute("hello", 2, 3.14f)]
class Program
{
    static void Main(string[] args)
    {
    }
}
1
ответ дан Alan 24 November 2019 в 05:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: