2008-11-06 7 views

Odpowiedz

142

Atrybuty przyjmą tablicę. Choć jeśli kontrolujesz atrybut, można również użyć params zamiast (który jest ładniejszy dla konsumentów, IMO):

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

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

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

składni dla tworzenia tablicy okazuje się być wyłączony:

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

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

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

Tak, ale trzeba zainicjować tablicę jesteś przejazdem w Oto przykład z testu wiersz w naszych testach jednostkowych, które testuje zmienną liczbę argumentów wiersza poleceń. ;

[Row(new[] { "-l", "/port:13102", "-lfsw" })] 
public void MyTest(string[] args) { //... } 
12

To powinno być w porządku. W specyfikacji, rozdział 17.2:

Wyrażenie E jest atrybut argumentu ekspresja jeśli wszystkie następujące stwierdzenia są prawdziwe:

  • typu E jest typu parametru cecha (§17.1 .3).
  • w czasie kompilacji, wartość E można rozwiązać w jeden z następujących sposobów:
    • stałą wartość.
    • Obiekt System.Type.
    • Jednowymiarowa tablica z atrybut-argument-wyrażeń.

Oto przykład:

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 
{ 
} 
+3

Uważaj na zgodność z CLS, ale –

16

Spróbuj deklarując konstruktor tak:

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

Wtedy można go używać jak:

[MyCustomAttribute(3, 4, 5)]

1

Możesz to zrobić. Innym przykładem może być:

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

[MyAttribute("hello", 2, 3.14f)] 
class Program 
{ 
    static void Main(string[] args) 
    { 
    } 
} 
30

Można zrobić, ale to nie jest zgodny z CLS:

[assembly: CLSCompliant(true)] 

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

Pokazy:

Warning 1 Arrays as attribute arguments is not CLS-compliant 

Do regularnego użycia refleksji może być korzystne posiadanie wielu atrybutów, tj.

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

Jednak to nie będzie działać z TypeDescriptor/PropertyDescriptor, gdzie tylko jedno wystąpienie jakiegokolwiek atrybutu jest obsługiwany (pierwszy lub ostatni wygrywa, nie pamiętam który).

+3

uwaga: wiele atrybutów wymaga atrybutu AttributeUsage w atrybucie. http://stackoverflow.com/questions/553540/how-to-create-duplicate-allowed- attribute – russau

1

Aby przywitać się z odpowiedzią Marka Gravella, tak można zdefiniować atrybut z parametrami tablicy, ale zastosowanie atrybutu z parametrem tablicy nie jest zgodne z CLS. Jednak samo zdefiniowanie atrybutu z właściwością array jest całkowicie zgodne z CLS.

Udało mi się zrozumieć, że Json.NET, biblioteka zgodna z CLS, ma klasę właściwości JsonPropertyAttribute z właściwością o nazwie ItemConverterParameters, która jest tablicą obiektów.