¿Cuáles son los atributos en .NET?

¿Cuáles son los atributos en .NET, para qué sirven y cómo creo mis propios atributos?

    Metadatos Datos sobre sus objetos / métodos / propiedades.

    Por ejemplo, podría declarar un atributo llamado: DisplayOrder para poder controlar fácilmente en qué orden deberían aparecer las propiedades en la UI. Podría agregarlo a una clase y escribir algunos componentes de la GUI que extraigan los atributos y ordenen los elementos de la interfaz de usuario de forma adecuada.

    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; } } } 

    De este modo, garantizo que SomeInt siempre se muestra antes de SomeDate cuando se trabaja con mis componentes personalizados de GUI.

    Sin embargo, los verá más comúnmente usados ​​fuera del entorno de encoding directa. Por ejemplo, el Diseñador de Windows los usa ampliamente para que sepa cómo tratar con objetos personalizados. Usando BrowsableAttribute de esta forma:

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

    Le dice al diseñador que no lo incluya en las propiedades disponibles en la ventana de Propiedades en tiempo de diseño, por ejemplo.

    También puede usarlos para la generación de código, las operaciones de precomstackción (como Post-Sharp) o las operaciones de tiempo de ejecución como Reflection.Emit. Por ejemplo, podría escribir un poco de código para crear perfiles que cubra de forma transparente cada llamada que hace su código y lo multiplica por el tiempo. Podrías “optar por no participar” en el tiempo a través de un atributo que colocas en métodos particulares.

     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); } } 

    Declararlos es fácil, solo crea una clase que herede de Attribute.

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

    Y recuerde que cuando usa el atributo puede omitir el sufijo “atributo” que el comstackdor agregará para usted.

    Muchas personas han respondido, pero nadie ha mencionado esto hasta ahora …

    Los atributos se usan mucho con la reflexión. La reflexión ya es bastante lenta.

    Merece la pena marcar tus atributos personalizados como clases sealed para mejorar su rendimiento en el tiempo de ejecución.

    También es una buena idea considerar dónde sería apropiado usar el lugar como un atributo, y atribuir su atributo (!) Para indicar esto a través de AttributeUsage . La lista de usos de atributos disponibles podría sorprenderlo:

    • Montaje
    • Módulo
    • Clase
    • Struct
    • Enum
    • Constructor
    • Método
    • Propiedad
    • Campo
    • Evento
    • Interfaz
    • Parámetro
    • Delegar
    • ReturnValue
    • Parámetro genérico
    • Todas

    También es bueno que el atributo AttributeUsage sea parte de la firma del atributo AttributeUsage. Whoa para dependencias circulares!

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

    Los atributos son un tipo de metadatos para las clases de etiquetado. Esto se usa a menudo en WinForms, por ejemplo, para ocultar controles de la barra de herramientas, pero se puede implementar en su propia aplicación para permitir que las instancias de diferentes clases se comporten de maneras específicas.

    Comience creando un 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 las clases de atributos deben tener el sufijo “Atributo” para ser válidas.
    Una vez hecho esto, crea una clase que use el atributo.

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

    Ahora puede verificar una clase específica ‘ SortOrderAttribute (si tiene una) haciendo lo siguiente:

     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; } } } 

    Si desea leer más acerca de esto, siempre puede consultar MSDN, que tiene una descripción bastante buena.
    ¡Espero que esto te haya ayudado!

    Un atributo es una clase que contiene un poco de funcionalidad que puede aplicar a objetos en su código. Para crear uno, crea una clase que herede de System.Attribute.

    En cuanto a para qué sirven … hay usos casi ilimitados para ellos.

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

    Los atributos son como metadatos aplicados a clases, métodos o conjuntos.

    Son buenos para cualquier cantidad de cosas (visualización del depurador, marcando las cosas como obsoletas, marcando las cosas como serializables, la lista es interminable).

    Crear tus propios personalizados es fácil como un pastel. Empieza aqui:

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

    En el proyecto en el que estoy trabajando actualmente, hay un conjunto de objetos UI de varios sabores y un editor para ensamblar estos objetos para crear páginas para usar en la aplicación principal, un poco como el diseñador de formularios en DevStudio. Estos objetos existen en su propio ensamblado y cada objeto es una clase derivada de UserControl y tiene un atributo personalizado. Este atributo se define así:

     [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; }; 

    y lo aplico a una clase como esta:

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

    que es lo que han dicho los carteles anteriores.

    Para usar el atributo, el editor tiene un Generic::List contiene los tipos de control. Hay un cuadro de lista desde el cual el usuario puede arrastrar y soltar en la página para crear una instancia del control. Para rellenar el cuadro de lista, obtengo ControlDescriptionAttribute para el control y llevo una entrada en la 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: lo anterior es C ++ / CLI, pero no es difícil convertirlo a C # (sí, lo sé, C ++ / CLI es una abominación, pero es con lo que tengo que trabajar :-()

    Puede poner atributos en la mayoría de las cosas y hay una amplia gama de atributos predefinidos. El editor mencionado anteriormente también busca atributos personalizados en las propiedades que describen la propiedad y cómo editarla.

    Una vez que tenga la idea completa, se preguntará cómo ha vivido sin ellos.

    Como se dijo, los atributos son relativamente fáciles de crear. La otra parte del trabajo es crear código que lo use. En la mayoría de los casos, usará la reflexión en tiempo de ejecución para modificar el comportamiento en función de la presencia de un atributo o sus propiedades. También hay escenarios en los que inspeccionará los atributos en el código comstackdo para realizar algún tipo de análisis estático. Por ejemplo, los parámetros pueden marcarse como no nulos y la herramienta de análisis puede usar esto como una sugerencia.

    Usar los atributos y conocer los escenarios apropiados para su uso es la mayor parte del trabajo.

    Los atributos son, esencialmente, los bits de datos que desea adjuntar a sus tipos (clases, métodos, eventos, enumeraciones, etc.)

    La idea es que en tiempo de ejecución algún otro tipo / framework / herramienta consultará su tipo para la información en el atributo y actuará sobre él.

    Por lo tanto, por ejemplo, Visual Studio puede consultar los atributos en un control de terceros para descubrir qué propiedades del control deberían aparecer en el panel Propiedades en tiempo de diseño.

    Los atributos también se pueden usar en la Progtwigción Orientada a Aspectos para inyectar / manipular objetos en tiempo de ejecución en función de los atributos que los decoran y agregar validación, registro, etc. a los objetos sin afectar la lógica comercial del objeto.

    Puede usar atributos personalizados como una forma simple de definir valores de tags en sub clases sin tener que escribir el mismo código una y otra vez para cada subclase. Encontré un buen ejemplo conciso de John Waters sobre cómo definir y usar atributos personalizados en tu propio código.

    Hay un tutorial en http://msdn.microsoft.com/en-us/library/aa288454(VS.71).aspx

    Para comenzar a crear un atributo, abra un archivo fuente C #, escriba el attribute y presione [TAB]. Se expandirá a una plantilla para un nuevo atributo.

    Los atributos también se usan comúnmente para la Progtwigción Orientada a Aspectos. Para ver un ejemplo de esto, echa un vistazo al proyecto PostSharp .