Quais são os atributos no .NET?

Quais são os atributos no .NET, para que servem e como eu crio meus próprios atributos?

    Metadados Dados sobre seus objects / methods / propriedades.

    Por exemplo, eu poderia declarar um Atributo chamado: DisplayOrder para que eu possa controlar facilmente em qual ordem as propriedades devem aparecer na interface do usuário. Eu poderia, então, anexá-lo a uma class e escrever alguns componentes da GUI que extraiam os atributos e ordenam os elementos da interface do usuário apropriadamente.

    public class DisplayWrapper { private UnderlyingClass underlyingObject; public DisplayWrapper(UnderlyingClass u) { underlyingObject = u; } [DisplayOrder(1)] public int SomeInt { get { return underlyingObject .SomeInt; } } [DisplayOrder(2)] public DateTime SomeDate { get { return underlyingObject .SomeDate; } } } 

    Assim, garantindo que o SomeInt seja sempre exibido antes do SomeDate ao trabalhar com os componentes personalizados da GUI.

    No entanto, você os verá mais comumente usados ​​fora do ambiente de codificação direta. Por exemplo, o Windows Designer usa-os extensivamente para saber como lidar com objects personalizados. Usando o BrowsableAttribute da seguinte forma:

     [Browsable(false)] public SomeCustomType DontShowThisInTheDesigner { get{/*do something*/} } 

    Diz ao designer para não listar isso nas propriedades disponíveis na janela Propriedades em tempo de design, por exemplo.

    Você também pode usá-los para geração de código, operações de pré-compilation (como Post-Sharp) ou operações em tempo de execução, como Reflection.Emit. Por exemplo, você poderia escrever um pouco de código para criação de perfil que envolvesse de forma transparente cada chamada que seu código faz e o tempo. Você pode “desativar” o tempo por meio de um atributo que você coloca em methods específicos.

     public void SomeProfilingMethod(MethodInfo targetMethod, object target, params object[] args) { bool time = true; foreach (Attribute a in target.GetCustomAttributes()) { if (a.GetType() is NoTimingAttribute) { time = false; break; } } if (time) { StopWatch stopWatch = new StopWatch(); stopWatch.Start(); targetMethod.Invoke(target, args); stopWatch.Stop(); HandleTimingOutput(targetMethod, stopWatch.Duration); } else { targetMethod.Invoke(target, args); } } 

    Declará-los é fácil, basta criar uma class que herde do Atributo.

     public class DisplayOrderAttribute : Attribute { private int order; public DisplayOrderAttribute(int order) { this.order = order; } public int Order { get { return order; } } } 

    E lembre-se que quando você usa o atributo você pode omitir o sufixo “atributo” o compilador irá adicionar isso para você.

    Muitas pessoas responderam, mas ninguém mencionou isso até agora …

    Atributos são usados ​​intensamente com reflection. A reflection já é bem lenta.

    Vale muito a pena marcar seus atributos personalizados como classs sealed para melhorar seu desempenho em tempo de execução.

    Também é uma boa ideia considerar onde seria apropriado usar um atributo desse tipo e atribuir seu atributo (!) Para indicar isso por AttributeUsage . A lista de usos de atributos disponíveis pode surpreendê-lo:

    • Montagem
    • Módulo
    • Classe
    • Struct
    • Enum
    • Construtor
    • Método
    • Propriedade
    • Campo
    • Evento
    • Interface
    • Parâmetro
    • Delegar
    • Valor de retorno
    • GenericParameter
    • Todos

    Também é legal que o atributo AttributeUsage seja parte da assinatura do atributo AttributeUsage. Whoa por dependencies circulares!

     [AttributeUsageAttribute(AttributeTargets.Class, Inherited = true)] public sealed class AttributeUsageAttribute : Attribute 

    Atributos são um tipo de meta-dados para classs de marcação. Isso é frequentemente usado no WinForms, por exemplo, para ocultar controles da barra de ferramentas, mas pode ser implementado em seu próprio aplicativo para permitir que instâncias de diferentes classs se comportem de maneiras específicas.

    Comece criando um atributo:

     [AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=true)] public class SortOrderAttribute : Attribute { public int SortOrder { get; set; } public SortOrderAttribute(int sortOrder) { this.SortOrder = sortOrder; } } 

    Todas as classs de atributos devem ter o sufixo “Atributo” para serem válidas.
    Depois disso, crie uma class que use o atributo.

     [SortOrder(23)] public class MyClass { public MyClass() { } } 

    Agora você pode verificar uma class específica ‘ SortOrderAttribute (se tiver uma) fazendo o seguinte:

     public class MyInvestigatorClass { public void InvestigateTheAttribute() { // Get the type object for the class that is using // the attribute. Type type = typeof(MyClass); // Get all custom attributes for the type. object[] attributes = type.GetCustomAttributes( typeof(SortOrderAttribute), true); // Now let's make sure that we got at least one attribute. if (attributes != null && attributes.Length > 0) { // Get the first attribute in the list of custom attributes // that is of the type "SortOrderAttribute". This should only // be one since we said "AllowMultiple=false". SortOrderAttribute attribute = attributes[0] as SortOrderAttribute; // Now we can get the sort order for the class "MyClass". int sortOrder = attribute.SortOrder; } } } 

    Se você quiser ler mais sobre isso, você sempre pode verificar o MSDN, que tem uma boa descrição.
    Espero que isso tenha te ajudado!

    Um atributo é uma class que contém um pouco de funcionalidade que você pode aplicar a objects em seu código. Para criar um, crie uma class que herda de System.Attribute.

    Quanto ao que eles são bons … há usos quase ilimitados para eles.

    http://www.codeproject.com/KB/cs/dotnetattributes.aspx

    Atributos são como metadados aplicados a classs, methods ou montagens.

    Eles são bons para qualquer número de coisas (visualização do debugger, marcando coisas como obsoletas, marcando coisas como serializáveis, a lista é infinita).

    Criando seus próprios personalizados é fácil como torta. Começa aqui:

    http://msdn.microsoft.com/en-us/library/sw480ze8(VS.71).aspx

    No projeto em que estou trabalhando atualmente, há um conjunto de objects de UI de vários tipos e um editor para montar esses objects para criar páginas para uso no aplicativo principal, um pouco como o designer de formulários no DevStudio. Esses objects existem em seu próprio assembly e cada object é uma class derivada de UserControl e possui um atributo personalizado. Este atributo é definido assim:

     [AttributeUsage (AttributeTargets::Class)] public ref class ControlDescriptionAttribute : Attribute { public: ControlDescriptionAttribute (String ^name, String ^description) : _name (name), _description (description) { } property String ^Name { String ^get () { return _name; } } property String ^Description { String ^get () { return _description; } } private: String ^ _name, ^ _description; }; 

    e eu aplico em uma class como esta:

     [ControlDescription ("Pie Chart", "Displays a pie chart")] public ref class PieControl sealed : UserControl { // stuff }; 

    que é o que os posters anteriores disseram.

    Para usar o atributo, o editor possui um Generic::List contendo os tipos de controle. Há uma checkbox de listview que o usuário pode arrastar e soltar na página para criar uma instância do controle. Para preencher a checkbox de listview, recebo o ControlDescriptionAttribute para o controle e preencho uma input na lista:

     // done for each control type array  // get all the custom attributes ^attributes = controltype->GetCustomAttributes (true); Type // this is the one we're interested in ^attributetype = ECMMainPageDisplay::ControlDescriptionAttribute::typeid; // iterate over the custom attributes for each (Object ^attribute in attributes) { if (attributetype->IsInstanceOfType (attribute)) { ECMMainPageDisplay::ControlDescriptionAttribute ^description = safe_cast  (attribute); // get the name and description and create an entry in the list ListViewItem ^item = gcnew ListViewItem (description->Name); item->Tag = controltype->Name; item->SubItems->Add (description->Description); mcontrols->Items->Add (item); break; } } 

    Nota: o acima é C ++ / CLI, mas não é difícil converter em C # (sim, eu sei, C ++ / CLI é uma abominação, mas é com o que tenho que trabalhar :-()

    Você pode colocar atributos na maioria das coisas e há toda a gama de atributos predefinidos. O editor mencionado acima também procura atributos personalizados nas propriedades que descrevem a propriedade e como editá-la.

    Depois de obter toda a idéia, você vai se perguntar como você viveu sem eles.

    Como dito, os atributos são relativamente fáceis de criar. A outra parte do trabalho é criar código que o use. Na maioria dos casos, você usará a reflection em tempo de execução para alterar o comportamento com base na presença de um atributo ou de suas propriedades. Há também cenários em que você inspecionará os atributos no código compilado para fazer algum tipo de análise estática. Por exemplo, os parâmetros podem ser marcados como não nulos e a ferramenta de análise pode usar isso como uma dica.

    Usar os atributos e conhecer os cenários apropriados para seu uso é a maior parte do trabalho.

    Atributos são, essencialmente, bits de dados que você deseja append aos seus tipos (classs, methods, events, enums, etc.)

    A idéia é que, em tempo de execução, algum outro tipo / estrutura / ferramenta irá consultar seu tipo para as informações no atributo e agir sobre ele.

    Portanto, por exemplo, o Visual Studio pode consultar os atributos em um controle de terceiros para descobrir quais propriedades do controle devem aparecer no painel Propriedades em tempo de design.

    Os atributos também podem ser usados ​​em Programação Orientada a Aspectos para injetar / manipular objects em tempo de execução com base nos atributos que os decoram e adicionar validação, log, etc. aos objects sem afetar a lógica de negócios do object.

    Você pode usar atributos personalizados como uma forma simples de definir valores de tags em subclasss sem ter que escrever o mesmo código repetidamente para cada subclass. Eu me deparei com um bom e conciso exemplo de John Waters sobre como definir e usar atributos personalizados em seu próprio código.

    Existe um tutorial em http://msdn.microsoft.com/en-us/library/aa288454(VS.71).aspx

    Para começar a criar um atributo, abra um arquivo de origem C #, digite o attribute e pressione [TAB]. Ele será expandido para um modelo para um novo atributo.

    Atributos também são comumente usados ​​para Programação Orientada a Aspectos. Para um exemplo disso, verifique o projeto PostSharp .