Atributos y reflexión (Cosas curiosas de C#, último post)

Atributos
Con esta largamente proyectada y nunca escrita (hasta ahora) entrada pretendo finalizar la serie de temas curiosos o novedosos (o más bien el hecho de que me hayan resultado curiosos a mí personalmente) sobre el lenguaje C#, para pasar a otras cosas. En algún lugar –hace ya bastante tiempo- dije que no me gustaban los atributos, al menos para realizar Interop con código nativo, pensando que la única finalidad de ellos era la citada, pero no es así, una parte de los atributos es el Interop, pero tiene muchas otras más, todas ellas interesantes, y como rectificar es de sabios –y no es que yo lo sea-, los atributos es una de las cosas que más me están gustando del .NET, ahora que empiezo a conocerlos en todo su esplendor.

Pero, ¿qué son los atributos? Son la forma de indicar dentro del código fuente que ciertos métodos o clases tienen un comportamiento especial definido mediante dichos atributos, amén de poder incluir toda una serie de metadatos dentro del código ejecutable para que sirva a nuestros propósitos o a los del entorno de ejecución. En pocas palabras, es mediante el uso de atributos como el .NET (y el Visual Studio) sabe la mayoría de cosas sobre el código que está ejecutando, así como su comportamiento.

Dicho esto, y tomando un ejemplo un tanto trivial, la construcción

[Serializable]
class Dato
{
    int d1,d2;
}

está indicando al compilador y al entorno de ejecución que la clase asociada es serializable, es decir, que puede ser guardada automáticamente en un flujo de datos, por lo que su implementación final dentro del código será algo diferente si no hubiera indicado dicho atributo.

Existen infinidad de atributos predefinidos que nos permiten desde hacer lo de arriba hasta indicar de qué forma se van a distribuir los datos en una estructura, pasando por indicar que una enumeración está compuesta de flags, potenciar la compilación condicional de forma que ciertos métodos se ejecuten como si estuvieran vacíos, marcar algo como obsoleto y que podría ser eliminado en siguientes versiones, utilizar código nativo y hacer llamadas a bibliotecas de terceros realizadas en otros lenguajes, y un larguísimo etcétera. La MSDN contiene una referencia completa sobre los atributos existentes si se busca la clase System.Attribute y se miran todas las clases que heredan de ella, lo que nos mete de lleno en el siguiente párrafo.

Y es que aparte de utilizar los existentes, también podemos crear nuestros propios atributos de forma sencilla, o más bien de la misma forma en que creamos nuestras propias clases: heredando de Attribute o de alguna de sus hijas. La utilidad de todo esto no es evidente a simple vista, pero lo cierto es que podría ser de mucha utilidad en la metaprogramación y en la creación de herramientas y extensiones al lenguaje. Imaginemos que estamos haciendo una herramienta para medir el código que cada programador realiza mediante la obligación de que cada programador marque su código con una propiedad que signifique su nombre y la fecha en que empezó el código. Es solo un ejemplo que no voy a detallar (más que nada porque ando algo falto de tiempo y porque es el ejemplo típico de la MSDN y de algún libro), pero su implementación mediante atributos es muy sencilla.

Claro está, si tenemos atributos personalizados debemos ser capaces de obtenerlos en tiempo de ejecución, si no de poco nos iban a servir. Y ello es completamente posible mediante el uso de typeof aplicado al elemento del que queremos obtenerlos. De nuevo en la MSDN tenemos varios ejemplos, que se entenderán mejor si antes seguimos el punto sobre la reflexión de esta entrada, ya que los citados se obtienen gracias a la misma.

Lo importante de todo esto está en que podemos cualificar y calificar nuestro propio código asociando metainformación que en determinadas situaciones podrían hacer que el código funcione de diferente forma a la deseada, o simplemente a incluir información extendida sobre lo que estamos haciendo, como tener un sistema de ayuda no sólo integrado en el código fuente, sino también disponible en tiempo de ejecución, que es la forma en la que está documentado en mayor parte el .NET y que las herramientas de desarrollo son capaces de obtener.

Reflexión
Una de las cosas que permiten los atributos, o más bien una de las cosas en las que los atributos forman parte directa e importante es la reflexión. No, no es cuestión de pensar, si no de, sin saber qué código vamos a cargar, poder ejecutarlo sin más o incluso lanzar métodos y acceder a elementos que teóricamente no están a nuestro alcance, como puede ser entrar y conocer el nivel de acceso privado de un objeto. Con la reflexión también podemos acceder a los atributos arriba citados.

Para entendernos diremos que es un paso más allá del OLE, ActiveX y COM, mucho más potente y seguro. Para un programador de C++, tanto los atributos como la reflexión son un RTTI a lo grande (realmente demasiado grande y con demasiado código oculto para que nos guste, pero eso no evita que esté ahí y que se pueda utilizar).

El primer paso consiste en obtener una referencia a un objeto de la clase Type mediante el método miembro GetType() que toda clase .NET y C# posee, incluso los tipos por valor (aquí es donde podemos ver una aplicación práctica a la dualidad clase-tipo de la que en su momento hablé y que, siendo sincero, sigue sin gustarme). También podemos utilizar la expresión typeof().

Luego podemos hacer muchas cosas con ello, desde la obtención de los atributos de un objeto como ya hemos dicho, o la ejecución de métodos que en principio no están accesibles, como el ejemplo de esta entrada mía, en la que explico cómo activar el doble buffer en un panel.

Lo cierto es que estas dos características dan al .NET Framework y a sus familiares cercanos una potencia nada desdeñable y a la que los programadores de sistemas no estamos acostumbrados.

4 comentarios sobre “Atributos y reflexión (Cosas curiosas de C#, último post)”

  1. hola tengo una tarea de programacion……..
    pero aun no se como contestar a ese programa….
    m gustaria q m ayudaran……………

    Se desea implementar un juego con las siguientes reglas:
    1. Se parte de una cantidad inicial de 15 fichas.
    2. Dos jugadores, de forma alterna, van retirando fichas del montón, permitiéndose
    en cada jugada retirar 1, 2 o 3 fichas.
    3. Pierde el jugador que retira la última ficha del montón.
    Implementar un programa que simule el juego descrito, de modo que se juegue contra la
    computadora.
    El orden de comienzo será al azar, siguiendo en todo momento la estrategia de retirar el
    número de fichas necesarias (1, 2 o 3) para que quede un montón con 13, 9, 5 o 1 ficha.
    Cada vez que sea el turno de la computadora, ésta informará de cuántas fichas retira y
    cuántas quedan en el montón.
    A continuación se le pedirá al usuario que introduzca el número de fichas que desea
    retirar, y se mostrará por pantalla igualmente cuántas fichas quedan en el montón. Este
    proceso se repetirá hasta que finalice la partida.

    este es mi problema….
    gracias ….. ojala puedan ayudarme….

Responder a anonymous Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *