2009-06-10 7 views
9

Realmente no entiendo los atributos. He leído todo tipo de libros & publicaciones en ellos, pero simplemente no lo entiendo.¿Cuál es la mejor manera de implementar atributos personalizados en dotnet/.NET?

Como no los entiendo, tampoco entiendo cómo usarlos efectivamente.

1) ¿Puede darme una buena definición de qué atributo es & para qué se utiliza?

2) ¿Puede darme un buen ejemplo de código en C# sobre cómo crear y consumir un atributo personalizado?

Respuesta

9

Supongamos que tiene una clase con una serie de propiedades que va a recorrer usando la reflexión. Cualquiera que sea cadenas puede necesitar ser validado para verificar que no excedan una cierta cantidad.

Podría crear un atributo textLength, con un constructor entero predeterminado y una propiedad/campo entero. Luego puede leer su atributo en cada propiedad de cadena de su clase y comparar la longitud del valor de la propiedad con el número especificado en el atributo.

Código:

public class TextLengthAttribute : Attribute 
{ 
    private int length; 
    public int Length { get { retrun length; } set { length = value; } } 

    public TextLengthAttribute(int num) { this.length = num ; } 
} 

public class MyClass 
{ 

    [TextLength(10)] 
    public string Property1; 
    [TextLength(20)] 
    public string Property2; 
} 

public class ClassReader 
{ 
    public static void Main() 
    { 
      MyClass example = MyClass.GetTestData(); 

      PropertyInfo[] props = typeof(MyClass).GetProperties(); 
      foreach (PropertyInfo prop in props) 
      { 
       if (prop.ValueType == typeof(String) 
       { 
        TextLengthAttribute[] atts = 
         (TextLengthAttribute)[]prop.GetCustomAttributes(
          typeof(TextLengthAttribute), false); 
        if (prop.GetValue(example, null).ToString().Length > 
         atts[0].Length) 
         throw new Exception(prop.name + " was too long"); 
       } 
      } 
    } 
} 

Nota: no probado

2

Tienen mucho en p. Ej. log4PostSharp. Usan atributos para introducir el comportamiento de AOP.

que es un atributo he usado una vez, para dar propiedades de una unidad (como segundos, metro, ...)

[AttributeUsage(AttributeTargets.Property)] 
public sealed class UnitAttribute : Attribute 
{ 
    public UnitAttribute(Unit unit) 
    { 
    Unit = unit; 
    } 

    public Unit Unit { get; private set; } 
} 

Fue utilizado en las propiedades, así:

[Unit(Unit.Meter)] 
public float Distance { get; set; } 

Usted luego puede recuperar el atributo para mostrarlo en la GUI.

11

Te podría dar un ejemplo, pero sería palidecen en comparación con este buen artículo:

Defining and Using Custom Attribute Classes in C#

El complejo, componente de estilo de desarrollo que las empresas esperan a cabo de desarrolladores de software modernas requiere mayor flexibilidad de diseño que las metodologías de diseño del pasado. Microsoft .NET Framework hace uso extenso de atributos para proporcionar funcionalidad adicional a través de lo que es conocido como programación "declarativa". Los atributos mejoran la flexibilidad en los sistemas de software porque promueven el acoplamiento flojo de la funcionalidad . Dado que puede crear sus propias clases de atributo personalizadas y luego actuar sobre ellas , puede aprovechar el poder de acoplamiento de los atributos para sus propios fines .

2

Un atributo se utiliza para proporcionar los metadatos acerca de cualquier miembro (campos, clase, etc.).

Puede crearlos heredando desde Attribute y consumirlos utilizando el método Attribute.GetCustomAttribute .

Un ejemplo de un atributo predeterminado es PrincipalPermissionAttribute que solo permite a los usuarios autenticados acceder a ciertos recursos.Por ejemplo:

[PrincipalPermission (SecurityAction.Demand, Role="Supervisor")] 
public class DoTheThingPage : Page 
{ 
    //// 
} 

En este ejemplo, tenemos una página ASP.NET que sólo puede ser visto por un usuario autenticado que pertenece a la función 'Supervisor'.

(Este atributo se lee de forma automática por el sub-sistema de seguridad en ASP.NET)

También tenga en cuenta que no se utilizó la parte 'atributo' del nombre de la clase, es una convención dentro de .NET.

3

Tenemos un requisito para mostrar los valores de Enum en un menú desplegable en un orden de clasificación específico. Implementamos el uso de Atributos Personalizados.

[AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field, AllowMultiple = false)] 
public class EnumSortAttribute : Attribute 
{ 
    public int SortOrder; 
    public bool SortByDescription; 
} 

[EnumSort(SortByDescription=true)] 
public enum EnumSortByDescription 
{ 
    [Description("enO")] 
    One = 1, 
    [Description("2")] 
    Two = 2, 
    Three = 3, 
    [Description("rouF")] 
    Four = 4 
} 

public enum EnumCustomSortOrder 
{ 
    [EnumSort(SortOrder = 3)] 
    One = 1, 
    [EnumSort(SortOrder = 1)] 
    Two = 2, 
    [EnumSort(SortOrder = 2)] 
    Three = 3 
} 
1

Atributo es sólo una manera de añadir información adicional (metadatos) a la clase, estructura o algún miembro. Este metadato podría ser recuperado por otro código para tomar algunas decisiones.

El ejemplo más simple es SerializableAttribute de .NET. Indica que la clase podría ser serializada por un BinaryFormatter más adelante.

Aquí es otro ejemplo - podríamos marcar algunas clases en nuestro código con ImmutableAttribute para indicar que no tienen ningún campo mutables y están bien para multihilo operaciones:

[Immutable] 
public sealed class ProcessingMessage 
{ 
    //... some code that should be thread-safe 

} 

Luego, podría crear una prueba unitaria que encuentre todas las clases con el atributo y se asegure de que they are immutable indeed:

[Test] 
public void Immutable_Types_Should_Be_Immutable() 
{ 
    var decorated = GlobalSetup.Types 
    .Where(t => t.Has<ImmutableAttribute>()); 

    foreach (var type in decorated) 
    { 
    var count = type.GetAllFields().Count(f => !f.IsInitOnly && !f.IsStatic); 
    Assert.AreEqual(0, count, "Type {0} should be immutable", type); 
    } 
} 
Cuestiones relacionadas