C # - Atributos
A attributeé uma tag declarativa que é usada para transmitir informações ao tempo de execução sobre os comportamentos de vários elementos como classes, métodos, estruturas, enumeradores, assemblies, etc. em seu programa. Você pode adicionar informações declarativas a um programa usando um atributo. Uma tag declarativa é representada por colchetes ([]) colocados acima do elemento para o qual é usada.
Os atributos são usados para adicionar metadados, como instruções do compilador e outras informações, como comentários, descrição, métodos e classes a um programa. O .Net Framework fornece dois tipos de atributos: os atributos predefinidos e os atributos personalizados construídos .
Especificando um Atributo
A sintaxe para especificar um atributo é a seguinte -
[attribute(positional_parameters, name_parameter = value, ...)]
element
O nome do atributo e seus valores são especificados entre colchetes, antes do elemento ao qual o atributo é aplicado. Os parâmetros posicionais especificam as informações essenciais e os parâmetros de nome especificam as informações opcionais.
Atributos Predefinidos
O .Net Framework fornece três atributos predefinidos -
- AttributeUsage
- Conditional
- Obsolete
AttributeUsage
O atributo pré-definido AttributeUsagedescreve como uma classe de atributo personalizado pode ser usada. Ele especifica os tipos de itens aos quais o atributo pode ser aplicado.
A sintaxe para especificar este atributo é a seguinte -
[AttributeUsage (
validon,
AllowMultiple = allowmultiple,
Inherited = inherited
)]
Onde,
O parâmetro validon especifica os elementos de linguagem nos quais o atributo pode ser colocado. É uma combinação do valor de um AttributeTargets enumerador . O valor padrão é AttributeTargets.All .
O parâmetro allowmultiple (opcional) fornece um valor para a propriedade AllowMultiple deste atributo, um valor booleano. Se isso for verdade, o atributo é multiuso. O padrão é falso (uso único).
O parâmetro inherited (opcional) fornece um valor para a propriedade Inherited deste atributo, um valor booleano. Se for verdadeiro, o atributo é herdado por classes derivadas. O valor padrão é falso (não herdado).
Por exemplo,
[AttributeUsage(
AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
Condicional
Este atributo predefinido marca um método condicional cuja execução depende de um identificador de pré-processamento especificado.
Isso causa a compilação condicional de chamadas de método, dependendo do valor especificado, como Debug ou Trace. Por exemplo, ele exibe os valores das variáveis durante a depuração de um código.
A sintaxe para especificar este atributo é a seguinte -
[Conditional(
conditionalSymbol
)]
Por exemplo,
[Conditional("DEBUG")]
O exemplo a seguir demonstra o atributo -
#define DEBUG
using System;
using System.Diagnostics;
public class Myclass {
[Conditional("DEBUG")]
public static void Message(string msg) {
Console.WriteLine(msg);
}
}
class Test {
static void function1() {
Myclass.Message("In Function 1.");
function2();
}
static void function2() {
Myclass.Message("In Function 2.");
}
public static void Main() {
Myclass.Message("In Main function.");
function1();
Console.ReadKey();
}
}
Quando o código acima é compilado e executado, ele produz o seguinte resultado -
In Main function
In Function 1
In Function 2
Obsoleto
Este atributo predefinido marca uma entidade de programa que não deve ser usada. Ele permite que você informe ao compilador para descartar um elemento de destino específico. Por exemplo, quando um novo método está sendo usado em uma classe e se você ainda deseja manter o método antigo na classe, você pode marcá-lo como obsoleto exibindo uma mensagem de que o novo método deve ser usado, em vez do método antigo.
A sintaxe para especificar este atributo é a seguinte -
[Obsolete (
message
)]
[Obsolete (
message,
iserror
)]
Onde,
O parâmetro mensagem é uma string que descreve o motivo pelo qual o item é obsoleto e o que usar em seu lugar.
O parâmetro iserror é um valor booleano. Se seu valor for verdadeiro, o compilador deve tratar o uso do item como um erro. O valor padrão é falso (o compilador gera um aviso).
O programa a seguir demonstra isso -
using System;
public class MyClass {
[Obsolete("Don't use OldMethod, use NewMethod instead", true)]
static void OldMethod() {
Console.WriteLine("It is the old method");
}
static void NewMethod() {
Console.WriteLine("It is the new method");
}
public static void Main() {
OldMethod();
}
}
Quando você tenta compilar o programa, o compilador fornece uma mensagem de erro informando -
Don't use OldMethod, use NewMethod instead
Criação de atributos personalizados
O .Net Framework permite a criação de atributos personalizados que podem ser usados para armazenar informações declarativas e podem ser recuperados em tempo de execução. Essas informações podem estar relacionadas a qualquer elemento de destino, dependendo dos critérios de design e da necessidade da aplicação.
Criar e usar atributos personalizados envolve quatro etapas -
- Declaração de um atributo personalizado
- Construindo o atributo personalizado
- Aplique o atributo personalizado em um elemento de programa de destino
- Acessando Atributos por meio de Reflexão
A última etapa envolve escrever um programa simples para ler os metadados e encontrar várias notações. Metadados são dados sobre dados ou informações usados para descrever outros dados. Este programa deve usar reflexos para acessar atributos em tempo de execução. Discutiremos isso no próximo capítulo.
Declaração de um atributo personalizado
Um novo atributo personalizado deve ser derivado do System.Attributeclasse. Por exemplo,
//a custom attribute BugFix to be assigned to a class and its members
[AttributeUsage(
AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
public class DeBugInfo : System.Attribute
No código anterior, declaramos um atributo personalizado denominado DeBugInfo .
Construindo o Atributo Personalizado
Vamos construir um atributo personalizado chamado DeBugInfo , que armazena as informações obtidas pela depuração de qualquer programa. Deixe-o armazenar as seguintes informações -
- O número do código do bug
- Nome do desenvolvedor que identificou o bug
- Data da última revisão do código
- Uma mensagem de string para armazenar as observações do desenvolvedor
A classe DeBugInfo possui três propriedades privadas para armazenar as três primeiras informações e uma propriedade pública para armazenar a mensagem. Conseqüentemente, o número do bug, o nome do desenvolvedor e a data da revisão são os parâmetros posicionais da classe DeBugInfo e a mensagem é um parâmetro opcional ou nomeado.
Cada atributo deve ter pelo menos um construtor. Os parâmetros posicionais devem ser passados pelo construtor. O código a seguir mostra a classe DeBugInfo -
//a custom attribute BugFix to be assigned to a class and its members
[AttributeUsage(
AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
public class DeBugInfo : System.Attribute {
private int bugNo;
private string developer;
private string lastReview;
public string message;
public DeBugInfo(int bg, string dev, string d) {
this.bugNo = bg;
this.developer = dev;
this.lastReview = d;
}
public int BugNo {
get {
return bugNo;
}
}
public string Developer {
get {
return developer;
}
}
public string LastReview {
get {
return lastReview;
}
}
public string Message {
get {
return message;
}
set {
message = value;
}
}
}
Aplicando o Atributo Personalizado
O atributo é aplicado colocando-o imediatamente antes de seu destino -
[DeBugInfo(45, "Zara Ali", "12/8/2012", Message = "Return type mismatch")]
[DeBugInfo(49, "Nuha Ali", "10/10/2012", Message = "Unused variable")]
class Rectangle {
//member variables
protected double length;
protected double width;
public Rectangle(double l, double w) {
length = l;
width = w;
}
[DeBugInfo(55, "Zara Ali", "19/10/2012", Message = "Return type mismatch")]
public double GetArea() {
return length * width;
}
[DeBugInfo(56, "Zara Ali", "19/10/2012")]
public void Display() {
Console.WriteLine("Length: {0}", length);
Console.WriteLine("Width: {0}", width);
Console.WriteLine("Area: {0}", GetArea());
}
}
No próximo capítulo, recuperamos informações de atributos usando um objeto da classe Reflection.