Pregunta

¿Cuáles son los atributos .NETA, ¿para qué son buenas, y ¿cómo puedo crear mis propios atributos?

¿Fue útil?

Solución

Los metadatos.Los datos acerca de los objetos/métodos/propiedades.

Por ejemplo, yo podría declarar un Atributo llamado:DisplayOrder, así que puede controlar en qué orden las propiedades deben aparecer en la interfaz de usuario.Entonces yo podría añadir a una clase y escribir algunos de los componentes de la GUI que extraer los atributos y el orden de los elementos de 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 ese modo asegurar que SomeInt siempre aparece antes de SomeDate cuando se trabaja con mi costumbre componentes de la GUI.

Sin embargo, los verás más comúnmente utilizado fuera del contacto directo con el entorno de programación.Por ejemplo, el Windows Diseñador utiliza ampliamente lo que se sabe cómo lidiar con la costumbre de los objetos.El uso de la BrowsableAttribute así:

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

Dice el diseñador no esta lista en las propiedades disponibles en la ventana de Propiedades en tiempo de diseño, por ejemplo.

Usted podría también utilizarlos para la generación de código, pre-compilar las operaciones (tales como Post-Sharp) o en tiempo de ejecución de las operaciones, tales como la Reflexión.Emiten.Por ejemplo, usted podría escribir un poco de código para la generación de perfiles que transparente envuelto cada llamada de su código hace y tiempos.Usted podría "opt-out" de la sincronización a través de un atributo que se coloca en particular los métodos.

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

Declarar de ellos es fácil, sólo tienes que hacer una clase que hereda de Atributo.

public class DisplayOrderAttribute : Attribute
{
    private int order;

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

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

Y recuerde que cuando usted utiliza el atributo puede omitir el sufijo "atributo" que el compilador de añadir que para usted.

NOTA: Los atributos no hacen nada por sí mismos, tiene que haber algún otro código que utiliza.A veces que el código ha sido escrito para usted, pero a veces usted tiene que escribir por ti mismo.Por ejemplo, el compilador de C# se preocupa por algunos y determinados marcos marcos usar algunos (por ejemplo,NUnit busca [TestFixture] en una clase y [Prueba] en un método de prueba cuando se carga un ensamblado).
Así que cuando la creación de su propio atributo personalizado ser consciente de que no tendrá impacto en el comportamiento de su código.Tendrás que escribir la otra parte que comprueba los atributos (a través de la reflexión) y actuar sobre ellos.

Otros consejos

Muchas personas han respondido, pero nadie ha mencionado este tan lejos...

Los atributos se utiliza en gran medida con la reflexión.La reflexión es ya bastante lento.

Es vale mucho la pena marca los atributos personalizados como sealed clases para mejorar su rendimiento en tiempo de ejecución.

También es una buena idea considerar donde sería apropiado utilizar el lugar de esos atributos, y atribuir su atributo (!) para indicar esto a través de AttributeUsage.La lista de atributo usos podrían sorprender:

  • Asamblea
  • Módulo
  • Clase
  • Struct
  • Enum
  • Constructor
  • Método
  • La propiedad
  • Campo
  • Evento
  • Interfaz
  • Parámetro
  • Delegado
  • ReturnValue
  • GenericParameter
  • Todos

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

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

Los atributos son una especie de meta-datos para el etiquetado de clases.Esto se utiliza a menudo en WinForms, por ejemplo, ocultar los controles de la barra de herramientas, pero puede ser implementado en su propia aplicación para habilitar instancias de clases diferentes a comportarse de maneras específicas.

Comience por crear 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 debe tener el sufijo "Attribute" para ser válido.
Una vez hecho esto, se debe crear una clase que utiliza el atributo.

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

Ahora, usted puede marcar una clase específica' SortOrderAttribute (si tiene uno) 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 usted puede comprobar siempre MSDN que tiene una descripción bastante buena.
Espero que esto te ha ayudado!

Un atributo es una clase que contiene algo de funcionalidad que se puede aplicar a los objetos en el código.Para crear una sola, crear una clase que hereda de System.Atributo.

Como para lo que son buenos para...hay casi infinitas posibilidades para ellos.

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

Los atributos son como los metadatos aplicados a las clases, métodos o asambleas.

Son buenos para cualquier número de cosas (depurador de visualización, marcando las cosas como obsoletos, marcando las cosas como serializable, la lista es interminable).

La creación de su propia personalizados es fácil como pastel.Comience aquí:

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

En el proyecto en el que estoy trabajando actualmente, existe un conjunto de objetos de interfaz de usuario de varios sabores y un editor para ensamblaje de estos objetos para crear páginas para su uso en la aplicación principal, un poco como el diseñador de formulario en DevStudio.Estos objetos existen en su propia asamblea y cada objeto de una clase derivada de UserControl y tiene un atributo personalizado.Este atributo se define como esto:

[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 yo se aplica a una clase como esta:

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

que es lo que el anterior carteles han dicho.

Usar el atributo, el editor tiene una Generic::List <Type> contiene los tipos de control.Hay un cuadro de lista que el usuario puede arrastrar desde y caer sobre la página para crear una instancia del control.Para rellenar el cuadro de lista, me da la ControlDescriptionAttribute para el control y llenar 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:el de arriba es C++/CLI, pero no es difícil convertir a C# (sí, lo sé, C++/CLI es una abominación, pero es lo que tengo que trabajar con :-( )

Usted puede poner los atributos en la mayoría de las cosas y hay toda la gama de atributos predefinidos.El editor se ha mencionado anteriormente también se ve con atributos personalizados en las propiedades que describen la propiedad y cómo editarlo.

Una vez que usted consigue la idea, te preguntarás cómo había podido vivir sin ellos.

Como se dijo, los Atributos son relativamente fáciles de crear.La otra parte de la obra es la creación de código que utiliza.En la mayoría de los casos usted va a utilizar la reflexión en tiempo de ejecución para modificar el comportamiento basado en la presencia de un atributo o de sus propiedades.También hay escenarios donde se va a inspeccionar los atributos en el código compilado para hacer algún tipo de análisis estático.Por ejemplo, los parámetros pueden ser marcados como no nulo y la herramienta de análisis puede utilizar esto como una sugerencia.

El uso de los atributos y conocer los escenarios adecuados para su uso es el grueso de la obra.

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

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

Así, por ejemplo, Visual Studio puede consultar los atributos en una 3ª parte de control de averiguar qué propiedades del control debe aparecer en el panel de Propiedades en tiempo de diseño.

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

Puede utilizar los atributos personalizados como una forma sencilla de definir los valores de etiqueta en sub clases sin tener que escribir el mismo código una y otra vez para cada subclase.Me encontré con una buena conciso ejemplo por John Waters de cómo definir y utilizar los atributos personalizados en su propio código.

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

Para comenzar la creación de un atributo, abrir un C# archivo de origen, tipo de attribute y pulsa [TAB].Se expandirá a una plantilla para un nuevo atributo.

Los atributos también son comúnmente utilizados para la Programación Orientada a Aspectos.Un ejemplo de esta retirar el PostSharp proyecto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top