118 votes

Puis-je initialiser un attribut C# avec un tableau ou un autre nombre variable d'arguments ?

Est-il possible de créer un attribut qui peut être initialisé avec un nombre variable d'arguments ?

Par exemple :

[MyCustomAttribute(new int[3,4,5])]  // this doesn't work
public MyClass ...

41voto

Marc Gravell Points 482669

Vous pouvez le faire, mais ce n'est pas conforme au CLS :

[assembly: CLSCompliant(true)]

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

Spectacles :

Warning 1   Arrays as attribute arguments is not CLS-compliant

Pour l'utilisation régulière de la réflexion, il peut être préférable d'avoir plusieurs attributs, c'est à dire

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

Cependant, cela ne fonctionnera pas avec TypeDescriptor / PropertyDescriptor où seule une instance unique d'un attribut est prise en charge (soit la première ou la dernière victoire, je ne me souviens plus laquelle).

26voto

Scott Dorman Points 25000

Essayez de déclarer le constructeur comme ceci :

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

Ensuite, vous pouvez l'utiliser comme :

[MyCustomAttribute(3, 4, 5)]

13voto

Jon Skeet Points 692016

Ça devrait aller. Dans les spécifications, section 17.2 :

Une expression E est un expression d'arguments d'attributs si toutes les affirmations suivantes sont vraies :

  • Le type de E est un type de paramètre d'attribut (§17.1.3).
  • Au moment de la compilation, la valeur de E peut être résolue par l'une des valeurs suivantes :
    • Une valeur constante.
    • Un objet System.Type.
    • Un tableau unidimensionnel de expressions d'arguments d'attributs .

Voici un exemple :

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

6voto

Rob Prouse Points 9193

Oui, mais vous devez initialiser le tableau que vous transmettez. Voici un exemple tiré d'un test de ligne dans nos tests unitaires qui teste un nombre variable d'options de ligne de commande ;

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

2voto

Alan Points 3381

Vous pouvez le faire. Un autre exemple pourrait être :

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

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X