Atributos

Concepto de atributo

    Un atributo es información que se puede añadir a los metadatos de un módulo de código. Esta información puede ser referente tanto al propio módulo o el ensamblado al que pertenezca como a los tipos de datos definidos en él, sus miembros, los parámetros de sus métodos, los bloques set y get de sus propiedades e indizadores o los bloques add y remove de sus eventos.

    En C# se incluyen numerosos modificadores que nos permiten asociar información a los metadatos de un módulo. Por ejemplo, con los modificadores public, protected, private, internal o protected internal podemos añadir información sobre la visibilidad de los tipos del módulo y de sus miembros. Pues bien, los atributos pueden verse como un mecanismo mediante el cual el programador puede crear sus propios modificadores.

    Un ejemplo de atributo podría ser uno llamado Ayuda que pudiese prefijar las definiciones de miembros de tipos e indicase cuál es la URL donde se pudiese encontrar información detallada con ayuda sobre el significado del miembro  prefijado.

Utilización de atributos

    Para colocar un atributo a un elemento basta prefijar la definición de dicho elemento con una estructura de esta forma:


[
<nombreAtributo>(<parámetros>)]

    Esta estructura ha de colocarse incluso antes que cualquier modificador que pudiese acompañar la definición del elemento a atribuir.

    Los parámetros de un atributo pueden ser opcionales, y si se usa sin especificar valores para sus parámetros no hay porqué que usar paréntesis vacíos como en las llamadas a métodos, sino que basta usar el atributo indicando sólo la sintaxis [<nombreAtributo>]

    Los parámetros de un atributo pueden ser de dos tipos:

  • Parámetros sin nombre: Se usan de forma similar a los parámetros de los métodos, sólo que no pueden contar con modificadores ref u out.

  • Parámetros con nombre: Son opcionales y pueden colocarse en cualquier posición en la lista de <parámetros> del atributo. Lo último se debe a que para darles valor se usa la sintaxis <nombreParámetro>=<valor>, con lo el compilador no dependerá de la posición en que se les pasen los valores para determinar a qué parámetro se le está dando cada valor, sino que recibe explícita su nombre.

    Para evitar conflictos entre parámetros con nombre y parámetros sin nombre, los primeros siempre se han de incluir después de los segundos, no siendo posible mezclarlos indiscriminadamente.

    Si se desean especificar varios atributos para un mismo elemento se pueden indicar todos ellos entre unos mismos corchetes separados por comas. Es decir, de la forma:


[
<atributo1>(<parametros1>), <atributo2>(<parámetros2>), ...]

    Aunque también sería posible especificarlos por separado. O sea, de esta otra forma:


[
<atributo1>(<parametros1>)] [<atributo2>(<parámetros2>)] ...

    Hay casos en los que por la ubicación del atributo no se puede determinar de manera unívoca a cuál elemento se le desea aplicar, ya que podría ser aplicable a varios. En esos casos, para evitar ambigüedades lo que se hace es usar el atributo prefijando su nombre de un indicador de tipo de elemento, quedando así la sintaxis a usar:


[
<indicadorElemento>:<nombreAtributo>(<parámetros>)]

    Aunque cada implementación de C# puede incluir sus propios indicadores de tipo de elemento, todas ellas incluirán al menos los siguientes:        

  • assembly: Indica que el atributo se aplica al ensamblado en que se compile el código fuente que lo contenga. Al definir atributos de ensamblado es obligatorio incluir este indicador, ya que estos atributos se colocan precediendo cualquier definición de clase o espacio de nombres y si no se incluyesen se confundiría con atributos de tipo, que se colocan en el mismo sitio.

  • module: Indica que el atributo se aplica al módulo en que se compile el código fuente que lo contenga. Al igual que el indicador assembly, hay que incluirlo siempre para definir este tipo de atributos porque si no se confundirían con atributos de tipo, ya que también se han de ubicar precediendo las definiciones de clases y espacios de nombres.

  • type: Indica que el atributo se aplica al tipo cuya definición precede. En realidad no hace falta utilizarlo, pues es lo que por defecto se considera para todo atributo que preceda a una definición de tipo. Sin embargo, se ha incluido por consistencia con el resto de indicadores de tipo de atributo y porque puede resultar conveniente incluirlo ya que explicitarlo facilita la lectura del código.

  • return: Indica que el atributo se aplica a un valor de retorno de un método, operador, bloque get, o definición de delegado. Si no se incluyese se consideraría que se aplica a la definición del método, operador, bloque get o delegado, ya que estos atributos se colocan antes de la misma al igual que los atributos de valores de retorno.

  • param: Indica que el atributo se aplica a un parámetro de un método. Si no se incluyese al definir bloques set, add o remove se consideraría que el atributo se refiere a los bloques en sí y no al parámetro value en ellos implícito.

  • method: Indica que el atributo se aplica al método al que precede. En realidad no es necesario usarlo porque, como se dice en la explicación de los indicadores param y return, es lo que se considera por defecto. Sin embrago, y como pasaba con type, se incluye por consistencia y porque puede ser buena idea incluirlo para facilitar la legibilidad del código con su explicitación.

  • event: Indica que el atributo se aplica al evento a cuya definición precede. En realidad no es necesario incluirlo porque es lo que se considera por defecto, pero nuevamente se ha incluido por consistencia y para facilitar la lectura del código.

  • property: Indica que el atributo se aplica a la propiedad a cuya definición precede. Éste también es un indicador innecesario e incluido tan sólo por consistencia y para facilitar la legibilidad del código.

  • field: Indica que el atributo se aplica al cuya definición precede. Como otros indicadores, sólo se incluye por consistencia y para hacer más legible el código
Atributos
José Antonio González Seco

José Antonio es experto en tecnologias Microsoft. Imparte cursos y conferencias en congresos sobre C# y .NET en Universidades de toda España (Sevilla, Barcelona, San Sebastián, Valencia, Oviedo, etc.) en representación de grandes empresas como Microsoft.
Fecha de alta:15/11/2006
Última actualizacion:15/11/2006
Visitas totales:46709
Valorar el contenido:
Últimas consultas realizadas en los foros
Últimas preguntas sin contestar en los foros de devjoker.com