2009-02-16 11 views
69

Estoy usando un atributo personalizado heredado de una clase de atributo. Lo estoy usando la siguiente manera:Cómo crear atributos duplicados permitidos

[MyCustomAttribute("CONTROL")] 
    [MyCustomAttribute("ALT")] 
    [MyCustomAttribute("SHIFT")] 
    [MyCustomAttribute("D")] 
    public void setColor() 
{ 

} 

Pero se muestra el error "atributo duplicado 'MyCustomAttribute'".
¿Cómo puedo crear un atributo permitido duplicado?

Respuesta

132

palillo de un atributo AttributeUsage en su clase Atributo (sí, eso es bocado) y establecer AllowMultiple a true:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] 
public sealed class MyCustomAttribute: Attribute 
+5

Simplemente curioso, ¿por qué una clase "sellada"? –

+15

Microsoft recomienda sellar clases de atributo siempre que sea posible: http://msdn.microsoft.com/en-us/library/2ab31zeh.aspx –

+1

¿Por qué sellado? En resumen: hace que la búsqueda de atributos sea más rápida y no tiene otro impacto. –

16

AttributeUsageAttribute ;-P

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] 
public class MyAttribute : Attribute 
{} 

Nótese, sin embargo, que si usted está utilizando ComponentModel (TypeDescriptor), solo admite una instancia de atributo (por tipo de atributo) por miembro; la reflexión en bruto admite cualquier número ...

3

Como alternativa, piense en rediseñar su atributo para permitir una secuencia.

[MyCustomAttribute(Sequence="CONTROL,ALT,SHIFT,D")] 

o

[MyCustomAttribute("CONTROL-ALT-SHIFT-D")] 

continuación, analizar los valores para configurar el atributo.

Para ver un ejemplo de esto echa un vistazo a AuthorizeAttribute en el código fuente de ASP.NET MVC en www.codeplex.com/aspnet.

+1

Incluso es posible que el constructor 'MyCustomAttribute' tome una * matriz * de cadenas, una' cadena [] ', con o sin el modificador' params'. Entonces podría aplicarse con la sintaxis '[MyCustom (" CONTROL "," ALT "," SHIFT "," D ")]' (con 'params'). –

11

Anton's solution es correcto, pero no es another gotcha.

En resumen, a menos que su attrbiute personalizado anule TypeId, acceder a él a través de PropertyDescriptor.GetCustomAttributes() solo devolverá una única instancia de su atributo.

1

Después de agregar la AttributeUsage, asegúrese de añadir esta propiedad a su clase Atributo

public override object TypeId 
{ 
    get 
    { 
    return this; 
    } 
} 
2

Por defecto, Attribute s están limitados a ser aplicado una vez a un solo campo/propiedad/etc. Esto se puede ver desde el definition of the Attribute class on MSDN:

[AttributeUsageAttribute(..., AllowMultiple = false)] 
public abstract class Attribute : _Attribute 

Por lo tanto, como han dicho otros, todas las subclases están limitados de la misma manera, y en caso de necesitar varias instancias del mismo atributo, es necesario establecer explícitamente AllowMultiple a true :

[AttributeUsage(..., AllowMultiple = true)] 
public class MyCustomAttribute : Attribute 

en atributos que permiten múltiples usos, you should also override the TypeId property para asegurar que las propiedades tales como PropertyDescriptor.Attributes funciona como se espera. La forma más sencilla de hacerlo es poner en práctica esa propiedad para devolver la instancia propio atributo:

[AttributeUsage(..., AllowMultiple = true)] 
public class MyCustomAttribute : Attribute 
{ 
    public override object TypeId 
    { 
     get 
     { 
      return this; 
     } 
    } 
} 

(Publicación de esta respuesta no porque los otros están equivocados, sino porque se trata de una respuesta más amplia/canónica.)

Cuestiones relacionadas