Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Para diseñar atributos personalizados, no es necesario aprender muchos conceptos nuevos. Si está familiarizado con la programación orientada a objetos y sabe cómo diseñar clases, ya tiene la mayoría de los conocimientos necesarios. Los atributos personalizados son clases tradicionales que derivan directa o indirectamente de la clase . Al igual que las clases tradicionales, los atributos personalizados contienen métodos que almacenan y recuperan datos.
Los pasos principales para diseñar correctamente clases de atributos personalizados son los siguientes:
Aplicar el AttributeUsageAttribute
Declaración de la clase de atributo
Declarar constructores
Declaración de propiedades
En esta sección se describe cada uno de estos pasos y se concluye con un ejemplo de atributo personalizado.
Aplicación de "AttributeUsageAttribute"
Una declaración de atributo personalizado comienza con el atributo , que define algunas de las características clave de la clase de atributo. Por ejemplo, puede especificar si el atributo se puede heredar por otras clases o a qué elementos se puede aplicar el atributo. En el fragmento de código siguiente se muestra cómo usar :
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
<AttributeUsage(AttributeTargets.All, Inherited:=False, AllowMultiple:=True)>
Public Class SomeClass
Inherits Attribute
'...
End Class
tiene tres miembros importantes para la creación de atributos personalizados: AttributeTargets, Inherited y AllowMultiple.
AttributeTargets (miembro)
En el ejemplo anterior, se especifica , que indica que este atributo se puede aplicar a todos los elementos del programa. Como alternativa, puede especificar , que indica que el atributo solo se puede aplicar a una clase o , lo que indica que el atributo solo se puede aplicar a un método . Todos los elementos del programa se pueden marcar para su descripción mediante un atributo personalizado de esta manera.
También puede pasar varios valores. El fragmento de código siguiente especifica que se puede aplicar un atributo personalizado a cualquier clase o método:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
<AttributeUsage(AttributeTargets.Class Or AttributeTargets.Method)>
Public Class SomeOtherClass
Inherits Attribute
'...
End Class
Propiedad heredada
La propiedad indica si el atributo se puede heredar por clases derivadas de las clases a las que se aplica el atributo. Esta propiedad acepta una marca (por defecto) o una marca . En el ejemplo siguiente, tiene un valor predeterminado de , mientras que tiene un valor de :
// This defaults to Inherited = true.
public class MyAttribute : Attribute
{
//...
}
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
public class YourAttribute : Attribute
{
//...
}
' This defaults to Inherited = true.
Public Class MyAttribute
Inherits Attribute
'...
End Class
<AttributeUsage(AttributeTargets.Method, Inherited:=False)>
Public Class YourAttribute
Inherits Attribute
'...
End Class
A continuación, los dos atributos se aplican a un método de la clase base :
public class MyClass
{
[MyAttribute]
[YourAttribute]
public virtual void MyMethod()
{
//...
}
}
Public Class MeClass
<MyAttribute>
<YourAttribute>
Public Overridable Sub MyMethod()
'...
End Sub
End Class
Por último, la clase se hereda de la clase base . El método muestra pero no :
public class YourClass : MyClass
{
// MyMethod will have MyAttribute but not YourAttribute.
public override void MyMethod()
{
//...
}
}
Public Class YourClass
Inherits MeClass
' MyMethod will have MyAttribute but not YourAttribute.
Public Overrides Sub MyMethod()
'...
End Sub
End Class
AllowMultiple (propiedad)
La propiedad indica si pueden existir varias instancias del atributo en un elemento . Si se establece en , se permiten varias instancias. Si se establece en (valor predeterminado), solo se permite una instancia.
En el ejemplo siguiente, tiene un valor predeterminado de , mientras que tiene un valor de :
//This defaults to AllowMultiple = false.
public class MyAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class YourAttribute : Attribute
{
}
' This defaults to AllowMultiple = false.
Public Class MyAttribute
Inherits Attribute
End Class
<AttributeUsage(AttributeTargets.Method, AllowMultiple:=true)>
Public Class YourAttribute
Inherits Attribute
End Class
Cuando se aplican varias instancias de estos atributos, se produce un error del compilador. En el ejemplo de código siguiente se muestra el uso válido de y el uso no válido de :
public class MyClass
{
// This produces an error.
// Duplicates are not allowed.
[MyAttribute]
[MyAttribute]
public void MyMethod()
{
//...
}
// This is valid.
[YourAttribute]
[YourAttribute]
public void YourMethod()
{
//...
}
}
Public Class MyClass
' This produces an error.
' Duplicates are not allowed.
<MyAttribute>
<MyAttribute>
Public Sub MyMethod()
'...
End Sub
' This is valid.
<YourAttribute>
<YourAttribute>
Public Sub YourMethod()
'...
End Sub
End Class
Si tanto la propiedad como la propiedad se establecen al , una clase que se hereda de otra clase puede heredar un atributo y tener otra vez el mismo atributo aplicado en la misma clase hija. Si se establece en , los valores de los atributos de la clase padre se sobrescribirán por nuevas instancias del mismo atributo en la clase hija.
Declaración de la clase de atributo
Después de aplicar el , empiece a definir los detalles de su atributo. La declaración de una clase de atributo es similar a la declaración de una clase tradicional, como se muestra en el código siguiente:
[AttributeUsage(AttributeTargets.Method)]
public class MyAttribute : Attribute
{
// . . .
}
<AttributeUsage(AttributeTargets.Method)>
Public Class MyAttribute
Inherits Attribute
' . . .
End Class
Esta definición de atributo muestra los siguientes puntos:
Las clases de atributo deben declararse como clases públicas.
Por convención, el nombre de la clase de atributo termina con la palabra Attribute. Aunque no es necesario, esta convención se recomienda para mejorar la legibilidad. Cuando se aplica el atributo, la inclusión de la palabra Attribute es opcional.
Todas las clases de atributo deben heredar directa o indirectamente de la clase .
En Microsoft Visual Basic, todas las clases de atributos personalizados deben tener el atributo System.AttributeUsageAttribute.
Declarar constructores
Al igual que las clases tradicionales, los atributos se inicializan con constructores. En el fragmento de código siguiente se muestra un constructor de atributos típico. Este constructor público toma un parámetro y establece una variable miembro igual a su valor.
public MyAttribute(bool myvalue)
{
this.myvalue = myvalue;
}
Public Sub New(myvalue As Boolean)
Me.myvalue = myvalue
End Sub
Puede sobrecargar el constructor para dar cabida a diferentes combinaciones de valores. Si también define una propiedad para la clase de atributo personalizada, puede usar una combinación de parámetros con nombre y posicional al inicializar el atributo. Normalmente, se definen todos los parámetros necesarios como posicionales y todos los parámetros opcionales como denominados. En este caso, el atributo no se puede inicializar sin el parámetro necesario. Todos los demás parámetros son opcionales.
Nota:
En Visual Basic, los constructores de una clase de atributo no deben usar un argumento ParamArray.
Los parámetros de constructor y las propiedades públicas de un atributo están restringidos a un conjunto limitado de tipos, ya que el tiempo de ejecución debe poder leer los valores de atributo directamente de los metadatos. Los tipos de parámetros de atributo válidos son:
Tipos simples (palabra clave de C#/ palabra clave Visual Basic o tipo de tiempo de ejecución de .NET):
C# Visual Basic tipo de tiempo de ejecución de .NET boolBooleanBoolean byteByteByte charCharChar doubleDoubleDouble floatSingleSingle intIntegerInt32 longLongInt64 shortShortInt16 stringStringString .
Tipos de enumeración a los que se puede acceder en el sitio de uso de atributos.
En C#, (cuando el valor es uno de los tipos de argumentos de atributo válidos o una matriz unidimensional de ellos).
Matrices unidimensionales de cualquiera de los tipos anteriores.
Si define un constructor que acepta un tipo fuera de esta lista, el atributo se compila correctamente, pero se produce un error del compilador al intentar aplicarlo. Para obtener más información sobre qué expresiones se permiten al aplicar un atributo, vea Aplicar atributos.
Nota:
Los tipos , , , , , y no son tipos de parámetros de atributo válidos, aunque admiten constantes literales.
En el ejemplo de código siguiente se muestra cómo se puede aplicar un atributo que usa el constructor anterior mediante parámetros opcionales y obligatorios. Se supone que el atributo tiene un valor booleano necesario y una propiedad de cadena opcional.
// One required (positional) and one optional (named) parameter are applied.
[MyAttribute(false, OptionalParameter = "optional data")]
public class SomeClass
{
//...
}
// One required (positional) parameter is applied.
[MyAttribute(false)]
public class SomeOtherClass
{
//...
}
' One required (positional) and one optional (named) parameter are applied.
<MyAttribute(false, OptionalParameter:="optional data")>
Public Class SomeClass
'...
End Class
' One required (positional) parameter is applied.
<MyAttribute(false)>
Public Class SomeOtherClass
'...
End Class
Declarar propiedades
Si desea definir un parámetro con nombre o proporcionar una manera sencilla de devolver los valores almacenados por el atributo, declare una propiedad. Las propiedades de atributo deben declararse como entidades públicas con una descripción del tipo de datos que se devolverá. Defina la variable que contendrá el valor de su propiedad y asígnela a los métodos y . En el ejemplo de código siguiente se muestra cómo implementar una propiedad en el atributo :
public bool MyProperty
{
get {return this.myvalue;}
set {this.myvalue = value;}
}
Public Property MyProperty As Boolean
Get
Return Me.myvalue
End Get
Set
Me.myvalue = Value
End Set
End Property
Ejemplo de atributo personalizado
En esta sección se incorpora la información anterior y se muestra cómo diseñar un atributo que documente información sobre el autor de una sección de código. El atributo de este ejemplo almacena el nombre y el nivel del programador y si se ha revisado el código. Usa tres variables privadas para almacenar los valores reales que se van a guardar. Cada variable se representa mediante una propiedad pública que obtiene y establece los valores. Por último, el constructor se define con dos parámetros necesarios:
[AttributeUsage(AttributeTargets.All)]
public class DeveloperAttribute : Attribute
{
// Private fields.
private string name;
private string level;
private bool reviewed;
// This constructor defines two required parameters: name and level.
public DeveloperAttribute(string name, string level)
{
this.name = name;
this.level = level;
this.reviewed = false;
}
// Define Name property.
// This is a read-only attribute.
public virtual string Name
{
get {return name;}
}
// Define Level property.
// This is a read-only attribute.
public virtual string Level
{
get {return level;}
}
// Define Reviewed property.
// This is a read/write attribute.
public virtual bool Reviewed
{
get {return reviewed;}
set {reviewed = value;}
}
}
<AttributeUsage(AttributeTargets.All)>
Public Class DeveloperAttribute
Inherits Attribute
' Private fields.
Private myname As String
Private mylevel As String
Private myreviewed As Boolean
' This constructor defines two required parameters: name and level.
Public Sub New(name As String, level As String)
Me.myname = name
Me.mylevel = level
Me.myreviewed = False
End Sub
' Define Name property.
' This is a read-only attribute.
Public Overridable ReadOnly Property Name() As String
Get
Return myname
End Get
End Property
' Define Level property.
' This is a read-only attribute.
Public Overridable ReadOnly Property Level() As String
Get
Return mylevel
End Get
End Property
' Define Reviewed property.
' This is a read/write attribute.
Public Overridable Property Reviewed() As Boolean
Get
Return myreviewed
End Get
Set
myreviewed = value
End Set
End Property
End Class
Puede aplicar este atributo mediante el nombre completo, , o mediante el nombre abreviado, , de una de las maneras siguientes:
[Developer("Joan Smith", "1")]
-or-
[Developer("Joan Smith", "1", Reviewed = true)]
<Developer("Joan Smith", "1")>
-or-
<Developer("Joan Smith", "1", Reviewed := true)>
En el primer ejemplo se muestra el atributo aplicado solo con los parámetros con nombre necesarios. En el segundo ejemplo se muestra el atributo aplicado con los parámetros obligatorios y opcionales.
Consulte también
- System.Attribute
- System.AttributeUsageAttribute
- Atributos
- Tipos de parámetros de atributo