Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você 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 reflexão.
Os atributos têm as seguintes propriedades:
- Os atributos adicionam metadados ao seu programa. Metadado é informação sobre os tipos definidos em um programa. Todos os assemblies .NET contêm um conjunto de metadados especificado que descreve os tipos e os membros de tipo definidos no assembly. Você pode adicionar atributos personalizados para especificar quaisquer outras informações necessárias.
- Atributos podem ser aplicados a assemblies inteiros, módulos ou elementos de programa menores, 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
APIs de Reflexão fornecidas por Type descrevem assemblies, módulos e tipos. Você pode usar a reflexão para criar dinamicamente uma instância de um tipo, associar 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 Attributes.
Aqui está um exemplo simples de reflexão com o GetType() método. Todos os tipos da Object
classe base herdam esse método, que é usado para obter o tipo de uma variável:
Nota
Certifique-se de adicionar as instruções using System;
e using System.Reflection;
na parte superior do seu 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 a reflexão para obter o nome completo do assembly carregado.
// Using Reflection to get information of an Assembly:
Assembly info = typeof(int).Assembly;
Console.WriteLine(info);
A saída deverá ser semelhante ao seguinte exemplo:
System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
Diferenças de palavra-chave para IL
As palavras-chave protected
C# e internal
não têm nenhum significado em IL (Linguagem Intermediária) e não são usadas nas APIs de reflexão. Os termos correspondentes na IL são Família e Assembly. Aqui estão algumas maneiras pelas quais você pode usar esses termos:
- Para identificar um
internal
método usando reflexão, use a IsAssembly propriedade. - Para identificar um método
protected internal
, use o IsFamilyOrAssembly.
Trabalhar com atributos
Os atributos podem ser colocados em quase qualquer declaração, embora um atributo específico possa restringir os tipos de declarações nas quais ele é válido. Em C#, especifique um atributo colocando o nome do atributo entre colchetes ([]
) acima da declaração da entidade à qual ela se aplica.
Neste exemplo, você usa o SerializableAttribute atributo 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 DllImportAttribute atributo:
[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 a multiutilização do ConditionalAttribute atributo:
[Conditional("DEBUG"), Conditional("TEST1")]
void TraceMethod()
{
// ...
}
Nota
Por convenção, todos os nomes de atributo terminam com o sufixo "Attribute" para distingui-los de outros tipos nas bibliotecas do .NET. No entanto, você não precisa especificar o sufixo de atributo ao usar atributos no código. Por exemplo, uma [DllImport]
declaração é equivalente a uma [DllImportAttribute]
declaração, 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 posicionais, sem nome ou nomeados. 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
- Sempre especifique primeiro
- Especificar em determinada ordem
- Sempre opcional, omita quando falso
- Especifique após os parâmetros posicionais
- Especificar em qualquer ordem
Por exemplo, o código a seguir mostra três atributos equivalentes DllImport
:
[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 primeiro. As outras instâncias são parâmetros nomeados. Nesse cenário, ambos os parâmetros nomeados têm o valor padrão de false, então podem ser omitidos. Consulte a documentação do atributo individual para obter informações sobre valores de parâmetro padrão. Para obter mais informações sobre tipos de parâmetro permitidos, consulte a seção atributos da especificação da linguagem C# .
Destinos do atributo
O destino de um atributo é a entidade à qual o atributo se aplica. Por exemplo, um atributo pode se aplicar 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 retornado.
Para identificar explicitamente um destino de atributo, use a seguinte sintaxe:
[target : attribute-list]
A tabela a seguir mostra a lista de valores possíveis target
.
Valor-alvo | Aplica-se a |
---|---|
assembly |
Montagem completa |
module |
Módulo de montagem atual |
field |
Campo em uma classe ou estrutura |
event |
Acontecimento |
method |
Método ou acessadores de propriedade get e set |
param |
Parâmetros de método ou parâmetros de acessador de propriedade set |
property |
Propriedade |
return |
Valor retornado de um método, indexador de propriedade ou acessador de propriedade get |
type |
Struct, classe, interface, enum ou delegado |
Você pode especificar o field
valor de destino para aplicar um atributo ao campo de backup 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; }
Nota
Independentemente dos destinos nos quais o ValidatedContract
atributo é definido como válido, o return
destino deve ser especificado, mesmo que o ValidatedContract
atributo seja definido para aplicar somente aos valores retornados. Em outras palavras, o compilador não usa as AttributeUsage
informações para resolver destinos de atributo ambíguos. Para obter mais informações, consulte AttributeUsage.
Examinar maneiras de usar atributos
Aqui estão algumas maneiras comuns de usar atributos no código:
- Marque os métodos do controlador que respondem às mensagens POST usando o
HttpPost
atributo. Para obter mais informações, consulte a classe HttpPostAttribute. - Descreva como realizar marshaling de parâmetros de 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 DllImportAttribute classe.
- Descreva o assembly em termos de versão, título, descrição ou marca.
- Descreva quais membros de uma classe devem ser serializados para persistência.
- Descreva como fazer mapeamento entre nós XML e membros de classe para serialização de XML.
- Descreva os requisitos de segurança para métodos.
- Especifique as características usadas para impor a segurança.
- Controle otimizações com compilador JIT (Just-In-Time) para que o código permaneça fácil de depurar.
- Obtenha informações sobre o chamador de um método.
Examinar cenários de reflexão
A reflexão é útil nos seguintes cenários:
- Acessar atributos nos metadados do programa. Para obter mais informações, consulte Recuperar informações armazenadas em atributos.
- Examine e instancie tipos em um assembly.
- Crie novos tipos em tempo de execução usando classes no System.Reflection.Emit namespace.
- Execute métodos de acesso e vinculação tardia em tipos criados em tempo de execução. Para obter mais informações, consulte Carregar e usar tipos dinamicamente.