C# - Apresentando Atributos


 Neste artigo vou apresentar os principais conceitos sobre atributos da linguagem C#.

O conceito de atributos pode parecer simples mas muita gente confunde atributos com propriedades de classes ou métodos.

Mas afinal o que é um atributo na linguagem C# ?

Os Atributos são um mecanismo para a adição/associação de metadados, tais como instruções do compilador e outros dados sobre seus assemblies,tipos, métodos, propriedades, etc.

Os atributos são inseridos nos metadados e são visíveis através ILDasm e outras ferramentas para leitura de metadados. Após você incluir um atributo em um programa ele poderá ser consultado via Reflection.

Assim, um atributo é um objeto que representa os dados que você deseja associar com um elemento no seu programa. O elemento ao qual você anexa um atributo é conhecido como o target (alvo) desse atributo.

A seguir temos os principais os alvos de atributos:

Nome do Membro Uso
All Aplicado a qualquer um dos seguintes elementos: assembly, class, class member, delegate, enum, event, field, interface, method, module, parameter, property, return value, ou struct
Assembly Aplicado ao próprio assembly
Class Aplicado a instância de classes
ClassMembers Aplicado a classes, structs, enums, constructors, methods, properties, fields, events, delegates, e interfaces
Constructor Aplicado a um dado constructor
Delegate Aplicado a método delegado
Enum Aplicado a uma enumeração (enumeration)
Event Aplicado a um evento (event)
Field Aplicado a um campo (field)
Interface Aplicado a uma interface
Method Aplicado a um método
Module Aplicado a um único módulo
Parameter Aplicado a um parâmetro de um método
Property Aplicado a uma propriedade (get e set, se implementado)
ReturnValue Aplicado a um valor retornado
Struct Aplicado a um struct

Propriedades dos atributos:

Usando Atributos

Os atributos podem ser colocados em praticameante qualquer declaração, embora um atributo específico possa restringir os tipos de declarações nas quais ele é válido. Na linguagem C#, você especifica um atributo colocando o nome do atributo entre colchetes ([ ]) acima da declaração da entidade à qual ele se aplica.

No exemplo a seguir temos o atributo SerializableAttribute que é usado para aplicar uma característica específica a uma classe:

[System.Serializable]  
public class Teste  
{  
    // Objetos deste tipo podem ser serializados  
}  

No exemplo a seguir temos uma classe onde o método Teste1 é decorado pelo atributo [Obsolete] que é usado de duas formas para alertar que este método é obsoleto :

public class Class1
{
        [Obsolete]
        public void Teste1()
        {
        }
        public void NovoTeste1()
        {
        }
}
public class Class1
{
      
 [Obsolete("Use o método NovoTeste1")]
        public void Teste1()
        {
        }
        public void NovoTeste1()
        {
        }
}

Outro exemplo é o atributo: [NoIDispatch]

Este atributo está associado a uma classe ou uma interface para indicar que a classe alvo deve derivar de IUnknown, em vez de IDispatch, ao exportar para COM.

Os atributos podem ser de dois tipos: intrínsecos e personalizado.

Se você procurar na CLR, você vai encontrar um grande número de atributos. Alguns atributos são aplicados a uma assembly, outros a uma classe ou interface, e alguns, como o [WebMethod], a membros da classe.

Podemos também combinar atributos quer seja empilhando um sobre o outro:

[assembly: AssemblyDelaySign (false)]
[assembly: AssemblyKeyFile ("\\KeyFile.snk.")]

quer seja separando os atributos com vírgulas:

[assembly: AssemblyDelaySign (false), assembly: AssemblyKeyFile ("\\KeyFile.snk.")]

Parâmetros de atributo

Muitos atributos têm parâmetros, que podem ser do tipo:  positional (posicionais), unnamed(não nomeados) e named(nomeados).

Por exemplo, esses três atributos são equivalentes:

[DllImport("user32.dll")]  
[DllImport("user32.dll", SetLastError=false, ExactSpelling=false)]  
[DllImport("user32.dll", ExactSpelling=false, SetLastError=false)]  

No primeiro parâmetro, o nome da DLL, é posicional e sempre vêm em primeiro lugar; os outros são nomeados.

Nesse caso, ambos os parâmetros nomeados são padronizados como false e, portanto, podem ser omitidos.

Criando atributos customizados

Para criar um atributo personalizado você precisa criar o atributo herdando da classe Attribute.

Vamos criar um atributo chamado AjudaAttribute que possui apenas uma propriedade Text.

  class AjudaAttribute : Attribute
  {
      public string TextoAjuda { get; set; }
  }

A seguir temos abaixo um exemplo de utilização do nosso atributo:

    class Cliente
    {
        private string _nome;
        [Ajuda(TextoAjuda = "Este é uma construtor")]
        public Cliente()
        {}
        [Ajuda(TextoAjuda = "Esta é uma propriedade")]
        public string Nome
        {
            get { return _nome; }
            set { _nome = value; }
        }
        [Ajuda(TextoAjuda = "Este é um método")]
        public void Metodo1()
        {
        }
    }

Um detalhe importante é que os atributos usados em uma classe são passíveis de serem herdados em classes filhas.

Para evitar esse comportamento podemos usar a propriedade Inherited em AttributeUsage definindo-a como false :

  [AttributeUsage(AttributeTargets.Property,Inherited=false)]
  class AjudaAttribute : Attribute
  {
      public string TextoAjuda { get; set; }
  }

Por padrão, um atributo só pode ser especificado uma única vez em uma declaração de membro ou tipo.

Para ignorar essa restrição, você deve definir o parâmetro chamado AllowMultiple boolean como true:

  [AttributeUsage(AttributeTargets.Property,AllowMultiple=true)]
  class AjudaAttribute : Attribute
  {
      public string TextoAjuda { get; set; }
  }

Assim, apresentei os principais conceitos sobre atributos.

E estamos conversados...

(Disse Jesus)"Mas a hora vem, e agora é, em que os verdadeiros adoradores adorarão o Pai em espírito e em verdade; porque o Pai procura a tais que assim o adorem."
João 4:23

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Referências:


José Carlos Macoratti