Compartilhar via


Atributos

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: