InicioArticulos y noticiasBases de datosProgramaciónForosInternetServiciosContratacionEmail
Tutorial C#
Introduccion a C#
Programacion con C#
Fundamentos de C#
Operadores
Instrucciones
Estrcuturas de control.
Definición de clases
Creación de objetos
Herencia y métodos virtuales
Polimorfismo
Ocultación de miembros
Miembros de tipo
Encapsulación
Espacios de nombres
Importación de espacios de nombres
Espacio de nombres distribuidos
Variables y tipos de datos
Tablas unidimensionales
Tablas multidimensionales
La clase System.Array
Cadenas de texto
Constantes
Orden de inicialización de variables
Métodos
Métodos externos
Constructores
Destructores
Propiedades
Indizadores
Redefinición de operadores
Delegados y eventos
La clase MulticastDelegate
Llamadas asíncronas
Implementación interna de los delegados
Eventos
Estructuras
Boxing y unboxing
Constructores de estructuras
Enumeraciones
Interfaces
Excepciones
Otras instrucciones
Atributos
Definición de nuevos atributos
Lectura de atributos en tiempo de ejecución
Atributos de compilación
Pseudoatributos
Código inseguro
Definición de punteros
Manipulación de punteros
Operadores relacionados con código inseguro
Fijación de variables apuntadas
Novedades de C# 2.0
Genéricos
Tipos parciales
Iteradores
Mejoras en la manipulación de delegados
Tipos anulables
Modificadores de visibilidad de bloques get y set
Clases estáticas
Referencias a espacios de nombres
Supresión temporal de avisos
Atributos condicionales
Incrustación de tablas en estructuras
Modificaciones en el compilador
También puedes ver ...
Creando cadenas de conexión ConnectionStrings en .net 3.5 o visual Studio 2008 usando SqlConnectionStringBuilder
Migración de WSE a WCF (Web Services de 2005 a 2008)
Generar archivos PDF con C#
TransactionScope - Simplificando el trabajo con transacciones.
LinQ To SQL - Un ejemplo sencillo
Cómo activar Intelisense (autocompletado) en el Web.config
Leer un campo XML de SQL Server 2005 con C#
TripleDES - Un ejemplo practico en C#
Mostrar un GridView dentro de un DataList
String.Format

Afiliados
La Web del programador
MundoProgramacion


 

Lectura de atributos en tiempo de ejecución

    Para acceder a los metadatos de cualquier ensamblado se utilizan las clases del espacio de nombres System.Reflection. Este espacio de nombres es  inmenso y explicar cómo utilizarlo queda fuera del alcance de este libro, aunque de todos modos a continuación se darán unas ideas básicas sobre cómo acceder a través de sus tipos a los atributos incluidos en los ensamblados.

    La clave para acceder a los atributos se encuentra en el método estático de la clase System.Attribute llamado Attribute[] GetCustomAttributes(<x> objetoReflexivo), donde <x> es el tipo de System.Reflection que representa a los elementos cuyos atributos se desea obtener. Los posibles tipos son: Assembly, que representa ensamblados, Module que representa módulos, MemberInfo que representa miembros (incluidos tipos, que al fin y al cabo son miembros de espacios de nombres), y ParameterInfo que representa parámetros. El parámetro tomado por este método será el objeto que represente al elemento en concreto cuyos metadatos se quieren obtener.

    Como se ve, GetCustomAttributes() devuelve una tabla con los atributos en forma de objetos Attribute, que es la clase base de todos los atributos, por lo que si a partir de ellos se desease acceder a características específicas de cada tipo de atributo habría que aplicar downcasting como se comentó en el Tema 5: Clases   (para asegurase de que las conversiones se realicen con éxito recuérdese que se puede usar el operador is para determinar cuál es el verdadero tipo de cada atributo de esta tabla)

    Para obtener el objeto Assembly que representa al ensamblado al que pertenezca el código que se esté ejecutando se usa el método Assembly GetExecutingAssembly() de la clase Assembly, que se usa tal y como se muestra:

	Assembly ensamblado = Assembly.GetExecutingAssembly(); 

           

   Otra posibilidad sería obtener ese objeto Assembly a partir del nombre del fichero donde se encuentre almacenado el ensamblado. Para ello se usa el método Assembly LoadFrom(string rutaEnsamblado) de la clase Assembly como se muestra:

	Assembly ensamblado = Assembly.LoadFrom("josan.dll"); 
 

    Una vez obtenido el objeto que representa a un ensamblado, pueden obtenerse los objetos Module que representan a los módulos que lo forman a través de su método Module[] GetModules().

    A partir del objeto Module que representa a un módulo puede obtenerse los objetos Type que representan a sus tipos a través de su método Type[]  GetTypes() Otra posibilidad sería usar el operador typeof ya visto para obtener el Type que representa a un tipo en concreto sin necesidad de crear objetos Module o Assembly.

    En cualquier caso, una vez obtenido un objeto Type, a través de sus métodos FieldInfo[] GetFields(), MethodInfo[] GetMethods(), ConstructorInfo[] GetConstructors(), EventInfo[] GetEvents[] y PropertyInfo[] GetProperties() pueden obtenerse los objetos reflexivos que representan, de manera respectiva, a sus campos, métodos, constructores, eventos y  propiedades o indizadores. Tanto todos estos objetos como los objetos Type derivan de MemberInfo, por lo que pueden ser pasados como parámetros de GetCustomAttributes() para obtener los atributos de los elementos que representan.

    Por otro lado, a través de los objetos MethodInfo y ConstructorInfo, es posible obtener los tipos reflexivos que representan a los parámetros de métodos y constructores llamando a su método ParameterInfo[] GetParameters() Además, en el caso de los objetos MethodInfo también es posible obtener el objeto que representa al tipo de retorno del método que representan mediante su propiedad Type ReturnType {get;}.

    En lo referente a las propiedades, es posible obtener los objetos MethodInfo que representan a sus bloques get y set a través de los métodos MethodInfo GetSetMethod() y MethodInfo GetSetMethod() de los objetos PropertyInfo que las representan. Además, para obtener los objetos reflexivos que representen a los índices de los indizadores también se dispone de un método ParamterInfo[] GetIndexParameters()

    Y en cuanto a los eventos, los objetos EventInfo disponen de métodos MethodInfo GetAddMethod() y MethodInfo GetRemoveMethod() mediante los que es posible obtener los objetos reflexivos que representan a sus bloques add y remove.

    A continuación se muestra un programa de ejemplo que lo que hace es mostrar por pantalla el nombre de todos los atributos que en él se hayan definido:

 
 using System.Reflection;
 using System;
 
 [assembly: EjemploEnsamblado]
 [module: EjemploModulo] 
 [AttributeUsage(AttributeTargets.Method)]
 class EjemploMétodo:Attribute
 {}
 
 [AttributeUsage(AttributeTargets.Assembly)]
 class EjemploEnsamblado:Attribute
 {}
 
 [AttributeUsage(AttributeTargets.Module)]
 class EjemploModulo:Attribute
 {}
 
 [AttributeUsage(AttributeTargets.Class)]
 class EjemploTipo:Attribute
 {}
 
 [AttributeUsage(AttributeTargets.Field)]
 class EjemploCampo:Attribute
 {}
 
 [EjemploTipo]
 class A
 {
  public static void Main()
  {
   Assembly ensamblado = Assembly.GetExecutingAssembly();
   
   foreach(Attribute atributo in Attribute.GetCustomAttributes(ensamblado))
    Console.WriteLine("ENSAMBLADO: {0}",atributo);
   
   foreach(Module modulo in ensamblado.GetModules())
   {
    foreach(Attribute atributo in Attribute.GetCustomAttributes(modulo))
     Console.WriteLine("MODULO: {0}", atributo);
    
    foreach (Type tipo in modulo.GetTypes())
    {
     foreach(Attribute atributo in Attribute.GetCustomAttributes(tipo))
      Console.WriteLine("TIPO: {0}", atributo);
     foreach (FieldInfo campo in tipo.GetFields())
      muestra("CAMPO", campo);
     foreach (MethodInfo metodo in tipo.GetMethods())
      muestra("METODO", metodo);
     foreach (EventInfo evento in tipo.GetEvents())
      muestra("EVENTO", evento);
     foreach (PropertyInfo propiedad in tipo.GetProperties())
      muestra("PROPIEDAD", propiedad);     
     foreach (ConstructorInfo constructor in tipo.GetConstructors())
      muestra("CONSTRUCTOR",constructor);
    }
   }
  }
  
  static private void muestra(string nombre, MemberInfo miembro)
  {
   foreach (Attribute atributo in Attribute.GetCustomAttributes(miembro))
    Console.WriteLine("{0}: {1}", nombre, atributo);
  }
 }

    Lo único que hace el Main() de este programa es obtener el Assembly que representa el ensamblado actual y mostrar todos sus atributos de ensamblado. Luego obtiene todos los Modules que representa a los módulos de dicho ensamblado, y muestra todos los  atributos de módulo de cada uno. Además, de cada módulo se obtienen todos los Types que representan a los tipos en él definidos y se muestran todos sus atributos; y de cada tipo se obtienen los objetos reflexivos que representan a sus diferentes tipos de miembros y se muestran los atributos de cada miembro.

    Aparte del método Main() en el ejemplo se han incluido definiciones de numerosos atributos de ejemplo aplicables a diferentes tipos de elemento y se han diseminado a lo largo del fuente varios usos de estos atributos. Por ello, la salida del programa es:


 ENSAMBLADO: EjemploEnsamblado

 ENSAMBLADO: System.Diagnostics.DebuggableAttribute

 MODULO EjemploModulo

 TIPO: System.AttributeUsageAttribute

 TIPO: System.AttributeUsageAttribute

 TIPO: System.AttributeUsageAttribute

 TIPO: System.AttributeUsageAttribute

 TIPO: System.AttributeUsageAttribute

 TIPO: EjemploTipo

 METODO: EjemploMétodo

    Nótese  que aparte de los atributos utilizados en el código fuente, la salida del programa muestra que el compilador ha asociado a nivel de ensamblado un atributo extra llamado Debuggable. Este atributo incluye información sobre si pueden aplicarse optimizaciones al compilar JIT el ensamblado o si se ha de realizar una traza de su ejecución. Sin embargo, no conviene fiarse de su implementación ya que no está documentado por Microsoft y puede cambiar en futuras versiones de la plataforma .NET.


Inicio | Tutorial C# Definición de nuevos atributosTutorial C#Atributos de compilación Versión para imprimir Foros de consulta


Añadir comentario ... Para preguntar utiliza los foros
Autor:

Título:


Para preguntar utiliza los foros.



Inicio | Tutorial C# Definición de nuevos atributosTutorial C#Atributos de compilación Versión para imprimir

Lectura de atributos en tiempo de ejecución
Autor: José Antonio González Seco
Visitas: 5590 Fecha de publicación: 30/11/2006
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.




Visitas: 310 | Comentarios: 0 | Archivo: Articulos
Categorias: Visual Basic .NET|C#|ASP.NET|ASP.NET|Programación|ADO.NET
27/09/2008 Navegando ....
Visitas: 85 | Comentarios: 0 | Archivo: Articulos
Categorias: Humor
Visitas: 207 | Comentarios: 0 | Archivo: Articulos
Categorias: Visual Basic .NET|C#|ASP.NET|ASP.NET|Programación|WCF
Visitas: 937 | Comentarios: 0 | Archivo: Articulos
Categorias: C#
Visitas: 209 | Comentarios: 0 | Archivo: Articulos
Categorias: JavaScript|ASP.NET
Visitas: 675 | Comentarios: 0 | Archivo: Articulos
Categorias: Windows XP|Linux|Windows Vista
Visitas: 455 | Comentarios: 0 | Archivo: Articulos
Categorias: Linux|BSD
Visitas: 236 | Comentarios: 0 | Archivo: Articulos
Categorias: Programación|Actualidad
18/08/2008 SQL Server 2008
Visitas: 1135 | Comentarios: 1 | Archivo: Articulos
Categorias: Transact-SQL
Visitas: 789 | Comentarios: 0 | Archivo: Articulos
Categorias: C#|ADO.NET|LinQ

Útimos temas recibidos en los foros ...
Coastal Inversiones SAC Coastal Vacations Oportunidad de Negocios por lecasur ... [ASP.NET] 0 11/10/2008
Negocios Rentables desde tu Hogar Coastal Vacations por lecasur ... [Access] 0 11/10/2008
COASTAL VACATIONS OPORTUNIDAD DE NEGOCIOS RENTABLES por lecasur ... [Actualidad] 0 11/10/2008
hacer el nombre de una tabla variable por leicolei ... [SQL Server] 2 10/10/2008
ayuda por yo ... [C#] 2 09/10/2008
Mostar nombre en una sesion de usuario por jhors ... [ASP.NET] 1 10/10/2008
Analista por Rolando ... [SQL Server] 0 10/10/2008
SQL dinámico en TRIGGERS por Alastor ... [ORACLE] 2 03/10/2008
Crystal Reports 8.5 por selvinalberto ... [Visual Basic 6.0] 0 10/10/2008
Agregar Columnas a un datagridview por Tony ... [Visual Basic .NET] 3 20/11/2007
Problema cargando un pl/sql Embebido en Pro*C por ejrivas ... [ORACLE] 0 10/10/2008
Verificar conexion a internet por giraldo ... [Visual Basic .NET] 3 11/12/2006

Access CGI JSP ORACLE UNIX
Actualidad HTML/DHTML/XHTML LINUX PHP Visual Basic .NET
ASP ISAPI MS DOS Power Builder Visual Basic 6.0
ASP.NET Java mySQL SQL WIN 98/NT/2000/XP
C# JavaScript Opinion SQL Server

devjoker  Te recomendamos además ...
28/08/2006 Ubuntu en VmWare con VMware Tools
27/08/2007 Enviar email con C#
01/06/2007 Autogenerado ESSALUD (Solución)
22/10/2005 Actualización de datos. UPDATE    forma parte de...Tutorial SQL
23/05/2006 Cursores en PL/SQL    forma parte de...Tutorial PL/SQL
06/05/2007 Introducción a Transact SQL    forma parte de...Tutorial de Transact SQL
15/06/2007 Control de errores en Transact SQL    forma parte de...Tutorial de Transact SQL
01/01/2006 Consultas agregadas    forma parte de...Tutorial SQL
11/12/2006 Genéricos    forma parte de...Tutorial C#
12/01/2006 Programación con PL/SQL    forma parte de...Tutorial PL/SQL

 

Encuesta
¿A que perfil te adaptas mejor?
[Ver] [Votar]