Codificando Atributos Personalizados
Para criar seus próprios atributos personalizados, você não precisa dominar muitos novos conceitos.Se você estiver familiarizado com programação orientada a objetos e sabe como criar classes, você já tem a maioria do conhecimento necessário.Atributos personalizados são classes essencialmente tradicionais que derivam de System.Attribute direta ou indiretamente.Exatamente como classes tradicionais, os atributos personalizados contêm métodos que armazenam e recuperam dados.
As etapas principais para criar corretamente classes de atributos personalizados são:
Aplicando o AttributeUsageAttribute
Declarar a classe de atributos
Declarar os construtores
Declarando propriedades
Esta seção descreve cada uma dessas etapas e termina com um exemplo do atributo personalizado.
Uma declaração de atributo personalizado começa com o AttributeUsageAttribute, que define algumas das principais características de chave de sua classe de atributos.Por exemplo, você pode especificar se o atributo pode ser herdado por outras classes ou especificar a quais elementos o atributo pode ser aplicado.O fragmento de código a seguir demonstra como usar a AttributeUsageAttribute .
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
<AttributeUsage(AttributeTargets.All, Inherited := False, AllowMultiple := true)>
The System.AttributeUsageAttribute tem três membros que são importantes para a criação de atributos personalizados: AttributeTargets, Herdadas, and AllowMultiple.
No exemplo anterior, AttributeTargets.All é especificada, indicando que este atributo pode ser aplicado a todos os elementos de programa.Como alternativa, você pode especificar AttributeTargets.Class , indicando que o atributo pode ser aplicado somente a uma classe, ou AttributeTargets.Method , indicando que o atributo pode ser aplicado somente a um método.Todos os elementos do programa podem ser marcados para descrição por um atributo personalizado dessa forma.
Você também pode passar várias instâncias de AttributeTargets.O fragmento de código a seguir especifica que um atributo personalizado pode ser aplicado a qualquer classe ou método.
[AttributeUsage (AttributeTargets.Class | AttributeTargets.Method)]
<AttributeUsage (AttributeTargets.Class Or AttributeTargets.Method)>
The Herdadas propriedade indica se o atributo pode ser herdado pelas classes derivadas de classes à qual seu atributo é aplicado.Essa propriedade tem um sinalizador TRUE (o padrão) ou FALSE.Por exemplo, no exemplo de código a seguir, MyAttribute possui um valor padrão Inherited de true , enquanto YourAttribute tem um valor Inherited de false.
//This defaults to Inherited = true.
public class MyAttribute :Attribute
{
}
[AttributeUsage( Inherited = false)]
public class YourAttribute : Attribute
{
}
<AttributeUsage( AttributeTargets.All, Inherited := True)> Public Class _
MyAttribute
Inherits Attribute
End Class
<AttributeUsage( AttributeTargets.All, Inherited := False)> Public Class _
YourAttribute
Inherits Attribute
End Class
Os dois atributos são então aplicados a um método na classe base MyClass.
public class MyClass
{
[MyAttribute]
[YourAttribute]
public virtual void MyMethod()
{
//...
}
}
' In Microsoft Visual Basic, you apply multiple attributes
' by separating them with commas.
Public Class [MyClass]
<MyAttribute, YourAttribute> Public Overridable Sub MyMethod()
'...
End Sub
End Class
Finalmene, a classe YourClass é herdada da classe base MyClass.O método MyMethod mostra MyAttribute, mas não YourAttribute.
public class YourClass: MyClass
{
//MyMethod will have MyAttribute but not YourAttribute.
public override void MyMethod()
{
//...
}
}
Public Class YourClass
Inherits [MyClass]
'MyMethod will have MyAttribute but not YourAttribute.
Public overrides Sub MyMethod()
'...
End Sub
End Class
A propriedade AllowMultiple indica se várias instâncias do seu atributo podem existir em um elemento.Se definido como true , várias instâncias são permitidas; se definido como False (o padrão), somente uma instância é permitida.
No exemplo de código a seguir, MyAttribute possui um valor padrão AllowMultiple de FALSE , enquanto YourAttribute tem um valor true .
//This defaults to AllowMultiple = false.
public class MyAttribute :Attribute
{
}
[AttributeUsage(AllowMultiple = true)]
public class YourAttribute : Attribute
{
}
'This defaults to AllowMultiple = false.
<AttributeUsage(AttributeTargets.Method)> Public Class _
MyAttribute
Inherits Attribute
End Class
<AttributeUsage(AttributeTargets.Method, AllowMultiple := True)> Public Class _
YourAttribute
Inherits Attribute
End Class
Quando várias instâncias desses atributos são aplicadas, MyAttribute produz um erro do compilador.O exemplo de código a seguir mostra o uso válido de YourAttribute e o uso inválido de MyAttribute.
public class MyClass
{
//This produces an error.
//Duplicates are not allowed.
[MyAttribute]
[MyAttribute]
public void MyMethod() {
//...
}
//This is valid.
[YourAttribute]
[YourAttribute]
public void YourMethod(){
//...
}
}
' In Microsoft Visual Basic you apply multiple attributes
' by separating them with commas.
Public Class [MyClass]
'This produces an error.
'Duplicates are not allowed.
<MyAttribute, MyAttribute> Public Overridable Sub MyMethod()
'...
End Sub
'This is valid.
<YourAttribute, YourAttribute> Public Sub YourMethod()
'...
End Sub
End Class
Se o AllowMultiple propriedade e oHerdadas propriedade estiver definida como True, uma classe é herdada de outra classe pode herdar um atributo e ter outra instância do mesmo atributo aplicada na mesma classe filho.Se AllowMultiple estiver definida como False , os valores de quaisquer atributos na classe pai serão substituídos por novas instâncias do mesmo atributo na classe filha.
Depois de aplicar a AttributeUsageAttribute, você pode começar a definir as especificidades do seu atributo.A declaração de uma classe de atributos parece com a declaração de uma classe tradicional, como demonstrado pelo código a seguir.
public class MyAttribute : System.Attribute
{
// . . .
}
' This attribute is only usable with methods
<AttributeUsage(AttributeTargets.Method)> Public Class MyAttribute
Inherits System.Attribute
' . . .
End Class
Esta definição de atributo demonstra os seguintes pontos:
Classes de atributo devem ser declaradas como classes públicas.
Por convenção, o nome da classe de atributos termina com a palavra Attribute.Enquanto não for necessária, esta convenção é recomendada para facilitar a leitura.Quando o atributo é aplicado, a inclusão de atributo de palavra é opcional.
Todas as classes de atributo devem herdar direta ou indiretamente de System.Attribute .
No Microsoft Visual Basic, todas as classes de atributos personalizados devem ter o atributo AttributeUsageAttribute.
Os atributos são inicializados com construtores da mesma forma como as classes tradicionais.O fragmento de código a seguir ilustra um típico construtor de atributos.Esse construtor público aceita um parâmetro e define seu valor igual a uma variável do membro.
public MyAttribute(bool myvalue)
{
this.myvalue = myvalue;
}
Public Sub New(newvalue As Boolean)
Me.myvalue = newvalue
End Sub
Você pode sobrecarregar o construtor para acomodar diferentes combinações de valores.Se você também definir uma propriedade para sua classe de atributos personalizados, você pode usar uma combinação de parâmetros nomeados e posicionais ao inicializar o atributo.Normalmente, você define todos os parâmetros necessários como posicionais e todos os parâmetros opcionais como nomeados.Nesse caso, o atributo não pode ser inicializado sem o parâmetro necessário.Todos os outros parâmetros são opcionais.Observe que em Visual Basic, construtores para uma classe de atributos não devem usar um argumento ParamArray.
O exemplo de código a seguir mostra como um atributo que usa que o construtor anterior pode ser aplicado usando parâmetros necessários e opcionais.Ele pressupõe que o atributo tem um valor booleano necessário e uma de sequência de caracteres opcional.
//One required (positional) and one optional (named) parameter are applied.
[MyAttribute(false, OptionalParameter = "optional data")]
//One required (positional) parameter is applied.
[MyAttribute(false)]
'One required (positional) and one optional (named) parameter are applied.
<MyAttribute(False, OptionalParameter := "optional data")>
' ...
'One required (positional) parameter is applied.
<MyAttribute(False)>
Se você deseja definir um parâmetro nomeado ou fornecer uma maneira fácil de retornar os valores armazenados pelo seu atributo, declare um propriedade.Propriedades de atributo devem ser declaradas como entidades públicas com uma descrição do tipo de dados que será retornado.Definir a variável que irá conter o valor de sua propriedade e associá-la aos métodos GET e SET.O exemplo de código a seguir demonstra como implementar uma propriedade simples em seu 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
Esta seção incorpora as informações anteriores e mostra como criar um atributo simples que documenta informações sobre o autor de uma seção do código.O atributo neste exemplo armazena o nome e o nível do programador, e se o código tenha sido revisado.Ele usa três variáveis privadas para armazenar os valores reais para salvar.Cada variável é representado por uma propriedade pública que obtém e define os valores.Finalmente, o construtor é definido com dois parâmetros necessários.
[AttributeUsage(AttributeTargets.All)]
public class DeveloperAttribute : System.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 System.Attribute
'Private fields.
Private m_name As String
Private m_level As String
Private m_reviewed As Boolean
'This constructor defines two required parameters: name and level.
Public Sub New(name As String, level As String)
Me.m_name = name
Me.m_level = level
Me.m_reviewed = False
End Sub
'Define Name property.
'This is a read-only attribute.
Public Overridable ReadOnly Property Name() As String
Get
Return m_name
End Get
End Property
'Define Level property.
'This is a read-only attribute.
Public Overridable ReadOnly Property Level() As String
Get
Return m_level
End Get
End Property
'Define Reviewed property.
'This is a read/write attribute.
Public Overridable Property Reviewed() As Boolean
Get
Return m_reviewed
End Get
Set
m_reviewed = value
End Set
End Property
End Class
Você pode aplicar este atributo usando o nome completo, DeveloperAttribute, ou o nome abreviado, Developer, em uma das seguintes maneiras.
[Developer("Joan Smith", "1")]
[Developer("Joan Smith", "1", Reviewed = true)]
<Developer("Joan Smith", "1")>
<Developer("Joan Smith", "1", Reviewed := True)>
O primeiro exemplo mostra o atributo aplicado apenas com os parâmetros nomeados ncessários, enquanto o segundo exemplo mostra o atributo aplicado com ambos os parâmetros necessários e opcionais.