Qué son los atributos in.NET?


¿Qué son los atributos en. NET, para qué sirven y cómo puedo crear mis propios atributos?

Author: Peter Mortensen, 2008-08-21

11 answers

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

Por ejemplo, podría declarar un atributo llamado: DisplayOrder para que pueda controlar fácilmente en qué orden deben aparecer las propiedades en la interfaz de usuario. Entonces podría añadirlo a una clase y escribir algunos componentes GUI que extraigan los atributos y ordenen los elementos de la interfaz de usuario apropiadamente.

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

Asegurando así que someInt siempre se muestra antes de SomeDate cuando se trabaja con mis componentes GUI personalizados.

Sin embargo, usted véalos más comúnmente utilizados fuera del entorno de codificación directa. Por ejemplo, el Diseñador de Windows los usa ampliamente para saber cómo lidiar con objetos hechos a medida. Usando el BrowsableAttribute así:

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

Le dice al diseñador que no lo enumere en las propiedades disponibles en la ventana Propiedades en el momento del diseño, por ejemplo.

Usted podría también usarlos para la generación de código, operaciones de pre-compilación (como Post-Sharp) u operaciones de tiempo de ejecución como Reflexión.Emitir. Por ejemplo, puedes escribir un poco de código para crear perfiles que envuelva de forma transparente cada llamada que tu código haga y la cronometre. Puede "optar por no" del tiempo a través de un atributo que coloca 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, simplemente haga una clase que hereda del Atributo.

public class DisplayOrderAttribute : Attribute
{
    private int order;

    public DisplayOrderAttribute(int order)
    {
        this.order = order;
    }

    public int Order
    {
        get { return order; }
    }
}

Y recuerda que cuando utilices el atributo puedes omitir el sufijo "attribute" el compilador lo añadirá por ti.

 142
Author: Quibblesome,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-15 15:41:45

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.

Es muy útil marcar sus atributos personalizados como sealed clases para mejorar su rendimiento en tiempo de ejecución.

También es una buena idea considerar dónde sería apropiado usar colocar tal atributo, y atribuir su atributo (!) para indicar esto vía AttributeUsage. La lista de los usos de atributos disponibles pueden sorprenderte:

  • Asamblea
  • Módulo
  • Clase
  • Estructura
  • Enum
  • Constructor
  • Método
  • Propiedad
  • Campo
  • Evento
  • Interfaz
  • Parámetro
  • Delegado
  • Valor de retorno
  • Parámetro genérico
  • Todos

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

[AttributeUsageAttribute(AttributeTargets.Class, Inherited = true)]
public sealed class AttributeUsageAttribute : Attribute
 35
Author: Drew Noakes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-16 18:02:10

Los atributos son un tipo de metadatos para etiquetar clases. 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 "Attribute" para ser válidas.
Una vez hecho esto, cree una clase que use el atributo.

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

Ahora usted puede comprobar un class' 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 sobre esto, siempre puede consultar MSDN que tiene una descripción bastante buena.
¡Espero que esto te haya ayudado!

 12
Author: Patrik Svensson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-05 09:25:02

Un atributo es una clase que contiene un poco de funcionalidad que puede aplicar a los objetos en su código. Para crear una, cree una clase que hereda del Sistema.Atributo.

En cuanto a lo que son buenos para... hay usos casi ilimitados para ellos.

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

 4
Author: TheSmurf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-21 16:00:51

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

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

Crear tus propios personalizados es muy fácil. Comience aquí:

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

 4
Author: Stu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-21 16:02:46

En el proyecto en el que estoy trabajando actualmente, hay un conjunto de objetos de interfaz de usuario de varios sabores y un editor para ensamblar estos objetos para crear páginas para su uso 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 tienen los carteles anteriores manifestó.

Para usar el atributo, el editor tiene un Generic::List <Type> que contiene los tipos de control. Hay un cuadro de lista que el usuario puede arrastrar y soltar en la página para crear una instancia del control. Para rellenar el list box, obtengo el ControlDescriptionAttribute para el control y lleno una entrada en la lista:

// done for each control type
array <Object ^>
  // 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 <ECMMainPageDisplay::ControlDescriptionAttribute ^> (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 convertir 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 toda la 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 tengas toda la idea, te preguntarás cómo has vivido sin ellos.

 4
Author: Skizz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-03 13:40:49

Como se ha dicho, 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, utilizará reflexión en tiempo de ejecución para alterar el comportamiento en función de la presencia de un atributo o sus propiedades. También hay escenarios en los que inspeccionará atributos en el código compilado para hacer algún tipo de análisis estático. Por ejemplo, los parámetros pueden estar marcados como no nulos y la herramienta de análisis puede usar esto como una pista.

Usando los atributos y conociendo la escenarios apropiados para su uso es la mayor parte del trabajo.

 3
Author: denis phillips,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-21 16:43:42

Los atributos son, esencialmente, 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.

Así que, por ejemplo, Visual Studio puede consultar los atributos de un control de terceros para averiguar qué propiedades del control deben aparecer en el panel Propiedades en el momento del diseño.

Atributos también se puede usar en Programació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 de negocio del objeto.

 3
Author: urini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-21 17:57:10

Puede usar atributos personalizados como una forma sencilla de definir valores de etiqueta en subclases sin tener que escribir el mismo código una y otra vez para cada subclase. Me encontré con un buen ejemplo conciso de John Waters de cómo definir y usar atributos personalizados en su propio código.

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

 2
Author: Chris Miller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-21 16:02:48

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

 2
Author: Jay Bazuzi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-27 01:55:40

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

 1
Author: Josh G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-21 20:21:38