Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Os atributos fornecem uma maneira poderosa de associar metadados, ou informações declarativas, ao código (assemblies, tipos, métodos, propriedades e assim por diante). Depois de associar um atributo a uma entidade de programa, você pode consultar o atributo em tempo de execução usando uma técnica chamada reflection.
Os atributos têm as seguintes propriedades:
- Os atributos adicionam metadados ao seu programa. Metadados é a informação sobre os tipos definidos em um programa. Todos os assemblies .NET contêm um conjunto especificado de metadados que descrevem os tipos e membros de tipo definidos no assembly. Você pode adicionar atributos personalizados para especificar quaisquer outras informações necessárias.
- Os atributos podem ser aplicados a assemblies inteiros, módulos ou elementos menores do programa, como classes e propriedades.
- Os atributos podem aceitar argumentos da mesma forma que métodos e propriedades.
- Os atributos permitem que um programa examine seus próprios metadados ou metadados em outros programas usando reflexão.
Trabalhar com reflexão
Reflection APIs fornecidas por Type descrevem assemblies, módulos e tipos. Você pode usar a reflexão para criar dinamicamente uma instância de um tipo, vincular o tipo a um objeto existente ou obter o tipo de um objeto existente e invocar seus métodos ou acessar seus campos e propriedades. Quando você usa atributos em seu código, a reflexão permite acessá-los. Para obter mais informações, consulte Atributos.
Aqui está um exemplo simples de reflexão com o método GetType(). Todos os tipos da classe base Object
herdam esse método, que é usado para obter o tipo de uma variável:
Observação
Certifique-se de adicionar as instruções using System;
e using System.Reflection;
na parte superior do arquivo de código C# (.cs).
// Using GetType to obtain type information:
int i = 42;
Type type = i.GetType();
Console.WriteLine(type);
A saída mostra o tipo:
System.Int32
O exemplo a seguir usa reflection para obter o nome completo do assembly carregado.
// Using Reflection to get information of an Assembly:
Assembly info = typeof(int).Assembly;
Console.WriteLine(info);
O resultado é semelhante ao seguinte exemplo:
System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
Diferenças de palavras-chave para IL
As palavras-chave C# protected
e internal
não têm significado na linguagem intermediária (IL) e não são usadas nas APIs de reflexão. Os termos correspondentes em IL são Family e Assembly. Aqui estão algumas maneiras de usar esses termos:
- Para identificar um método
internal
usando reflexão, use a propriedade IsAssembly. - Para identificar um método
protected internal
, use o IsFamilyOrAssembly.
Trabalhar com atributos
Os atributos podem ser colocados em quase todas as declarações, embora um atributo específico possa restringir os tipos de declarações nas quais é válido. Em C#, você especifica um atributo colocando o nome do atributo entre colchetes ([]
) acima da declaração da entidade à qual ele se aplica.
Neste exemplo, você usa o atributo SerializableAttribute para aplicar uma característica específica a uma classe:
[Serializable]
public class SampleClass
{
// Objects of this type can be serialized.
}
Você pode declarar um método com o atributo DllImportAttribute:
[System.Runtime.InteropServices.DllImport("user32.dll")]
extern static void SampleMethod();
Você pode colocar vários atributos em uma declaração:
void MethodA([In][Out] ref double x) { }
void MethodB([Out][In] ref double x) { }
void MethodC([In, Out] ref double x) { }
Alguns atributos podem ser especificados mais de uma vez para uma determinada entidade. O exemplo a seguir mostra multiuso do atributo ConditionalAttribute:
[Conditional("DEBUG"), Conditional("TEST1")]
void TraceMethod()
{
// ...
}
Observação
Por convenção, todos os nomes de atributos terminam com o sufixo "Atributo" para distingui-los de outros tipos nas bibliotecas .NET. No entanto, você não precisa especificar o sufixo de atributo quando você usa atributos no código. Por exemplo, uma declaração [DllImport]
é equivalente a uma declaração [DllImportAttribute]
, mas DllImportAttribute
é o nome real da classe na Biblioteca de Classes do .NET.
Parâmetros de atributo
Muitos atributos têm parâmetros, que podem ser posicional, sem nome ou nomeado. A tabela a seguir descreve como trabalhar com atributos nomeados e posicionais:
Parâmetros posicionais
Parâmetros do construtor de atributo:
Parâmetros nomeados
Propriedades ou campos do atributo:
- Deve especificar, não pode omitir
- Especifique sempre primeiro
- Especificar em uma determinada ordem
- Sempre opcional, omitir quando falso
- Especifique após os parâmetros posicionais
- Especificar em qualquer ordem
Por exemplo, o código a seguir mostra três atributos DllImport
equivalentes:
[DllImport("user32.dll")]
[DllImport("user32.dll", SetLastError=false, ExactSpelling=false)]
[DllImport("user32.dll", ExactSpelling=false, SetLastError=false)]
O primeiro parâmetro, o nome da DLL, é posicional e sempre vem em primeiro lugar. As outras instâncias são nomeadas parâmetros. Nesse cenário, ambos os parâmetros nomeados têm padrão como false, pelo que podem ser omitidos. Consulte a documentação do atributo individual para obter informações sobre valores de parâmetros padrão. Para obter mais informações sobre os tipos de parâmetros permitidos, consulte a seção Atributos da especificação da linguagem C# .
Destinos de atributos
O destino do de um atributo é a entidade à qual o atributo se aplica. Por exemplo, um atributo pode ser aplicado a uma classe, um método ou um assembly. Por padrão, um atributo se aplica ao elemento que o segue. Mas você também pode identificar explicitamente o elemento a ser associado, como um método, um parâmetro ou o valor de retorno.
Para identificar explicitamente um destino de atributo, use a seguinte sintaxe:
[target : attribute-list]
A tabela a seguir mostra a lista de possíveis valores de target
.
Valor alvo | Aplica-se a |
---|---|
assembly |
Montagem completa |
module |
Módulo de montagem atual |
field |
Campo em uma classe ou uma estrutura |
event |
Evento |
method |
Método ou acessores de propriedade get e set |
param |
Parâmetros do método ou parâmetros do acessor de propriedade set |
property |
Propriedade |
return |
Valor de retorno de um método, indexador de propriedade, ou acessor de propriedade get |
type |
Estrutura, classe, interface, enumeração ou delegado |
Você pode especificar o valor de destino field
para aplicar um atributo ao campo de suporte criado para uma propriedade implementada automaticamente.
O exemplo a seguir mostra como aplicar atributos a assemblies e módulos. Para obter mais informações, consulte Atributos comuns (C#).
using System;
using System.Reflection;
[assembly: AssemblyTitleAttribute("Production assembly 4")]
[module: CLSCompliant(true)]
O exemplo a seguir mostra como aplicar atributos a métodos, parâmetros de método e valores de retorno de método em C#.
// default: applies to method
[ValidatedContract]
int Method1() { return 0; }
// applies to method
[method: ValidatedContract]
int Method2() { return 0; }
// applies to parameter
int Method3([ValidatedContract] string contract) { return 0; }
// applies to return value
[return: ValidatedContract]
int Method4() { return 0; }
Observação
Independentemente dos destinos nos quais o atributo ValidatedContract
é definido como válido, o destino return
deve ser especificado, mesmo que o atributo ValidatedContract
seja definido para se aplicar apenas aos valores de retorno. Em outras palavras, o compilador não usa as informações AttributeUsage
para resolver alvos de atributos ambíguos. Para obter mais informações, consulte AttributeUsage.
Rever formas de utilizar atributos
Aqui estão algumas maneiras comuns de usar atributos no código:
- Marque os métodos do controlador que respondem a mensagens POST usando o atributo
HttpPost
. Para obter mais informações, consulte a classe HttpPostAttribute. - Descreva como organizar parâmetros do método ao interoperar com código nativo. Para obter mais informações, consulte a classe MarshalAsAttribute.
- Descreva as propriedades COM (Component Object Model) para classes, métodos e interfaces.
- Chame o código não gerenciado usando a classe DllImportAttribute.
- Descreva sua montagem em termos de título, versão, descrição ou marca registrada.
- Descreva quais membros de uma classe devem ser serializados para persistência.
- Descreva como mapear entre membros de classe e nós XML para serialização XML.
- Descreva os requisitos de segurança para métodos.
- Especifique as características usadas para impor a segurança.
- Controle otimizações com o compilador just-in-time (JIT) para que o código permaneça fácil de depurar.
- Obtenha informações sobre o chamador para um método.
Rever cenários de reflexão
A reflexão é útil nos seguintes cenários:
- Acesse atributos nos metadados do seu programa. Para obter mais informações, consulte Recuperando informações armazenadas em atributos.
- Examine e instancie tipos em um assembly.
- Crie novos tipos em tempo de execução usando classes no namespace System.Reflection.Emit.
- Execute métodos de vinculação e acesso tardios em tipos criados em tempo de execução. Para obter mais informações, consulte Carregar e usar tipos dinamicamente.