Cómo trabajar con atributos en C #

Los atributos son una característica poderosa en el lenguaje de programación C # que puede agregar información de metadatos a sus ensamblados.

Un atributo es en realidad un objeto que está asociado con cualquiera de estos elementos: ensamblado, clase, método, delegado, enumeración, evento, campo, interfaz, propiedad y estructura. Se pueden usar para asociar información declarativa; puede recuperar dicha información en tiempo de ejecución en un momento posterior si es necesario utilizar la reflexión. En otras palabras, puede usar atributos para inyectar información adicional a los ensamblados que se puede consultar en tiempo de ejecución si es necesario mediante la reflexión. Un atributo consta de su nombre y, opcionalmente, una lista de parámetros. El nombre del atributo corresponde a la clase de atributo.

Puede aprovechar los atributos para validar los objetos comerciales en su aplicación. Hay dos tipos de atributos: atributos intrínsecos y atributos personalizados. Mientras que el primero está disponible como parte del marco .Net, el segundo se puede implementar derivando una clase de la clase System.Attribute. El MSDN dice: "Un atributo es una pieza de información declarativa adicional que se especifica para una declaración".

Entremos ahora en algo de código. El atributo Obsolete se puede usar para denotar un método como obsoleto, uno que ya no se debe usar porque ya no es necesario o puede tener alguna otra alternativa. El siguiente fragmento de código ilustra cómo puede utilizar el atributo Obsolete en la parte superior de una declaración de método.

[Obsolete("This method is obsolete...")]

        public static void DoSomeWork()

        {

            //Some code

        }

Si usa este método en su código y compila su programa, verá una advertencia en la ventana de salida del IDE de Visual Studio. Por lo tanto, puede ignorar esta advertencia si lo desea. Ahora, ¿qué pasa si quieres que tus desarrolladores no usen este método en absoluto? Bueno, luego puede usar el segundo parámetro (aunque es opcional) mientras declara el atributo Obsolete. Aquí está la versión modificada del método DoSomeWork (). Observe el uso del parámetro booleano esta vez.

[Obsolete("This method is obsolete...", true)]

        public static void DoSomeWork()

        {

                       //Some code

        }                                                                                                                        

Cuando pasa "true" como el segundo parámetro opcional esta vez y compila su programa, el código no se compila en absoluto. Eso es lo que querías hacer, ¿no?

Atributos personalizados

En esta sección exploraremos cómo podemos implementar atributos personalizados. Los atributos personalizados son clases que heredan la clase System.Attribute. Por lo tanto, para implementar una clase de atributo personalizada, cree una nueva clase y derívala de la clase System.Attribute como se muestra a continuación.

using System;

public class CustomAttribute : Attribute

{

}

Para controlar el uso de atributos personalizados, puede aprovechar la clase AttributeUsage. Esta clase contiene propiedades como ValidOn, AllowMultiple y Inherited que pueden usarse para controlar el uso de su atributo personalizado.

El siguiente fragmento de código ilustra una versión modificada de nuestra clase de atributo personalizado. Tenga en cuenta el uso de un constructor que acepta una cadena como argumento y la asigna al miembro de cadena privada de la clase. Esto es solo para fines ilustrativos.

[AttributeUsage(AttributeTargets.All)]

    public class CustomAttribute : Attribute

    {

        private string text;

        public CustomAttribute(string text)

        {

            this.Text = text;

        }

        public string Text

        {

            get

            {

                return this.text;

            }

            set

            {

                this.text = value;

            }

        }

    }

También puede especificar los destinos de atributo a los que se debe aplicar su atributo personalizado. Así es como puede hacerlo.

[AttributeUsage(AttributeTargets.Class |

AttributeTargets.Constructor |

AttributeTargets.Field |

AttributeTargets.Method |

AttributeTargets.Property,

AllowMultiple = true)]

    public class CustomAttribute : Attribute

    {

        private string text;

        public CustomAttribute(string text)

        {

            this.Text = text;

        }

        public string Text

        {

            get

            {

                return this.text;

            }

            set

            {

                this.text = value;

            }

        }

    }

Ahora puede usar la reflexión para mostrar todos los atributos que se aplican a un objeto en particular usando el siguiente fragmento de código.

MemberInfo memberInfo = typeof(CustomAttribute);

object[] attributes = memberInfo.GetCustomAttributes(true);

for (int i = 0, j = attributes.Length; i < j; i++)

  {

     Console.WriteLine(attributes[i]);

  }

Ahora considere la siguiente clase en la que aplicaríamos nuestro atributo personalizado.

[CustomAttribute("Hello World...")]

public class SomeClass

{

}

Observe cómo se ha utilizado el atributo personalizado y se le ha pasado un texto como argumento. El siguiente fragmento de código ilustra cómo puede imprimir el contenido de la propiedad Text.

MemberInfo memberInfo = typeof(SomeClass);

object[] attributes = memberInfo.GetCustomAttributes(true);

foreach (object attribute in attributes)

{

CustomAttribute customAttribute = attribute as CustomAttribute;

if (customAttribute != null)

Console.WriteLine("Text = {0}", customAttribute.Text);

else

Console.WriteLine();

}