Foro de elhacker.net

Programación => .NET (C#, VB.NET, ASP) => Mensaje iniciado por: [D4N93R] en 2 Junio 2010, 17:50 pm



Título: [Tutorial] Introducción a System.Reflection
Publicado por: [D4N93R] en 2 Junio 2010, 17:50 pm
Introducción a System.Reflection

Reflection es la habilidad que tiene un código para revisar su propia estructura, es decir, podemos revisar la metadata que está en el assembly (en el caso de .net) y manipularla a nuestro antojo.

Con Reflection podemos encontrar cuarquier detalle sobre un objecto, assembly, propiedad, además de poder invocar métodos y obtener o establecer valores de una propiedad, todo ésto en tiempo de ejecución!

Esta habilidad nos da poder en nuestro código pero como todo,  hay que saber utilizarlo en el momento preciso y no abusar sobre el uso de Reflection ya que nuestro código podría verse afectado por pérdidas de performance.

Se preguntarán dónde y cuándo hay que utilizar Reflection, pues es algo que tienen que saber utilizar cuando lo necesiten, hay situaciones como formularios que requieren un diseño dinámico según el tipo que se pase en X parámetro, y en ese momento se preguntarán: "¿Escribo el formulario a hardcode, o utilizo reflection?", éste es uno de los casos más utilizados, también pódemos usarlo para serializar objectos de forma personalizada, etc.

¿Cómo comienzo a utilizar reflection?

Hay dos formas de comenzar: La primera es usando typeof() y la segunda es utilizando el método GetType() que todos los objectos tienen. Cualquiera de las dos formas que se usen retornan un objeto tipo Type, ese type es el que nos otorga la información de ese tipo.

Entre los principales métodos de Type tenemos:

  • GetField() Obtiene el campo según el nombre.
  • GetMethod() Obtiene un método, y si éste tiene sobre cargas, al igual que el constructor, hay que pasarle el tipo correspondiente de la sobre carga.
  • GetProperty() Obtiene la propiedad según el nombre.

Nota: aparte de los métodos anteriores existen los mismos en plural, es decir que en vez de obtener un miembro, obtienes un arreglo con los resultados según los parámetros que le indiques. Ejm: GetProperty() tienes:  GetProperties() el cual  puedes llamar sin parámetros para obtener un PropertyInfo[] con todas las propiedades.

Un punto muy importante es que en todo ésto, aunque hayamos sacado toda ésta información a partir de una instancia, Reflection se basa en metadata, es decir todo lo que exploramos y manipulamos, lo hacemos sin la instancia inicial, es por eso que cuando se vaya a invocar un método, a establecer valores en campos o propiedades, etc, nos pidan la instancia a la cual queremos realizar ese trabajo.


Título: Re: Introducción a System.Reflection
Publicado por: [D4N93R] en 2 Junio 2010, 17:51 pm
Para todos los ejemplos usaremos la siguiente clase:

Código
  1.  
  2. public class Person
  3. {
  4.     private string m_firstName;
  5.     private string m_lastName;
  6.  
  7.     public string FirstName
  8.     {
  9.          get { return m_firstName; }
  10.          set { m_firstName = value; }
  11.      }
  12.  
  13.     public string LastName
  14.     {
  15.          get { return m_lastName; }
  16.          set { m_lastName = value; }
  17.      }
  18.  
  19.      public void Run()
  20.      {   }
  21. }
  22.  
  23.  


Título: Re: Introducción a System.Reflection
Publicado por: [D4N93R] en 2 Junio 2010, 17:57 pm
GetField() y GetFields()

GetField nos regresa un FieldInfo y GetFields nos retorna un arreglo de FieldInfo, el cual podemos iterar.

FieldInfo tiene dos métodos muy importantes que son: GetValue y SetValue. Con GetValue obtenemos el valor que está almacenado en la instancia que pasemos como parámetro. Y SetValue establecemos a la instancia que pasamos como primer parámetro el valor que pongamos como segundo parámetro.

Ejemplo:

Código
  1. Person p = new Person();
  2.  
  3. Type t = p.GetType();
  4.  
  5. FieldInfo fInfo = t.GetField("m_firstName", BindingFlags.NonPublic | BindingFlags.Instance);
  6.  
  7. fInfo.SetValue(p,"Juan");
  8.  
  9.  

Bueno en primer lugar creamos una instancia de Person, luego obtenemos el tipo. De éste utilizamos GetField y el pasamos como parámetro el nombre del campo que queremos obtener, y también pasamos (BindingFlags.NonPublic | BindingFlags.Instance) como segundo parámetro, noten que es de tipo Flag, por lo que podemos pasar más de uno separado por el símbolo de pipe o tubería |. El BindingFlags.NonPublic es para decirle al método que el campo no es publico (obviamente). Y BindingFlags.Instance hace que el resultado sea de campos que se instancien,y no de campos estáticos. Luego de obtenerlo usamos el método SetValue al cual le pasa la instancia y el valor que se le quiere asignar al campo.



GetMethod() y GetMethods()

Al igual que GetFields, GetMethods nos retorna un arreglo pero de MethodInfo.

MethodInfo entre sus métodos podemos encontrar a GetParámeters y al Invoke, GetParámeters obtiene un arreglo con los parámetros, e Invoke que es el que va a hacer la llamada al método.

Para utilizarlo se hace de la siguiente manera:

Código
  1. Person p = new Person();
  2.  
  3. Type t = p.GetType();
  4.  
  5. MethodInfo mInfo = t.GetMethod("Run");
  6.  
  7. mInfo.Invoke(p, null);

Ejecutamos el GetMethod y le pasamos el nombre del método, nos retorna MethodInfo. Del MethodInfo ejecutamos el Invoke y le pasamos la instancia y como el método Run() no tiene parámetros le pasamos null, en caso contrario sería simplemente pasar un arreglo de object con los parámetros en el orden que aparecen en el método.

Nota: Invoke retorna object, así que si el método que están llamando tiene algún valor de retorno, solo sería cuestion de hacerle un cast: ejm:  

Código
  1. string nombre = (string) mInfo.Invoke(p, null);

GetProperty() y GetProperties()

Por último y no menos importante (de hecho es el que más he usado), están los GetProperty() que retorna un PropertyInfo y GetProperties() que retorna PropertyInfo[].

Los PropertyInfo funcionan parecido a los FieldInfo, tenemos GetValue y SetValue. Ahora un ejemplo:

Código
  1. Person p = new Person();
  2.  
  3. Type t = p.GetType();
  4.  
  5. PropertyInfo pInfo = t.GetProperty("FirstName");
  6.  
  7. string name = (string) pInfo.GetValue(p, new object[] {} );


Espero prontos extender más este tema.


Título: Re: [Tutorial] Introducción a System.Reflection
Publicado por: raul338 en 2 Junio 2010, 23:18 pm
:O queee lindooo!!! :) (?

Esta muy bueno (lo vi por encima, ni lo lei todavia pero...) me gusta el tema.
 

Lindo aporte


Título: Re: [Tutorial] Introducción a System.Reflection
Publicado por: BlackZeroX en 2 Junio 2010, 23:55 pm

mmm creo que con esto puedo sustituir mi CallByName() del Basic tradicional... ya vere que tal xP.

Dulce Infierno Lunar!¡.


Título: Re: [Tutorial] Introducción a System.Reflection
Publicado por: [D4N93R] en 3 Junio 2010, 02:12 am
Gracias..

Si Reflection te resuelve mucho la vida en muchas ocasiones, todo tiene un costo, en este caso con Reflection se pierde un poco el rendimiento, pero es casi imperceptible, dependiendo de la situación obviamente.

Saludos!


Título: Re: [Tutorial] Introducción a System.Reflection
Publicado por: Zzombi en 6 Junio 2010, 03:33 am
no me quedo muy claro cuando se debe utilizar  :-\


Título: Re: [Tutorial] Introducción a System.Reflection
Publicado por: [D4N93R] en 6 Junio 2010, 03:49 am
En realidad no es uno de los namespaces más usados dentro del framework en aplicaciones cotidianas; pero es muy útil en algunos casos específicos. Te doy un ejemplo, yo una vez necesité hacer un SDK para un software de mi autoría, dentro del SDK cree ciertas interfaces y clases para la creación de addons para la aplicación en cuestión.

Bueno, Cómo logré que luego de programar un Addon poder cargalo en la aplicación? Pues utilizando Reflection puedes leer, examinar y ejecutar clases y ensamblados sin necesidad de tener tu el codigo, ni ninguna referencia directa.

Un saludo!


Título: Re: [Tutorial] Introducción a System.Reflection
Publicado por: Zzombi en 6 Junio 2010, 04:11 am
sería como un hook  :huh:

por lo que dices en el ejemplo, está bastante interesante  :D


Título: Re: [Tutorial] Introducción a System.Reflection
Publicado por: [D4N93R] en 6 Junio 2010, 04:17 am
No No un hook, eso es otra cosa. :) Reflection es un tema medio-avanzado, te recomiendo que leas algo más sencillo antes de adentrarte en estas clases.

Un saludo!


Título: Re: [Tutorial] Introducción a System.Reflection
Publicado por: Zzombi en 6 Junio 2010, 22:30 pm
te recomiendo que leas algo más sencillo antes de adentrarte en estas clases.

algo como que?  ;D
para ponerme a leer


Título: Re: [Tutorial] Introducción a System.Reflection
Publicado por: [D4N93R] en 7 Junio 2010, 04:29 am
Comienza con acceso a datos..

ADO.NET


Título: Re: [Tutorial] Introducción a System.Reflection
Publicado por: Zzombi en 7 Junio 2010, 05:02 am
Comienza con acceso a datos..

ADO.NET

eso ya lo vi.. también el acceso a datos con el namespace Common
en fin... ya encontre algo para pulirme más  :P

gracias D4N93R


Título: Re: [Tutorial] Introducción a System.Reflection
Publicado por: [D4N93R] en 7 Junio 2010, 05:14 am
Seguro, luego mira algo sobre XML y después puedes ir por Streams, luego Sockets y Threads, y depués Reflection..


Título: Re: [Tutorial] Introducción a System.Reflection
Publicado por: Zzombi en 7 Junio 2010, 05:23 am
los sockets y threads los traigo del lenguaje C  :P
XML no se nada  :xD


Título: Re: [Tutorial] Introducción a System.Reflection
Publicado por: raul338 en 7 Junio 2010, 07:05 am
los sockets y threads los traigo del lenguaje C  :P
XML no se nada  :xD
Mira que aca los sokets cambian en cierta forma :P

Sobre xml es bueno y abunda en .net, es un gran tema aunque paresca simple :P

De ultima, clases cortas: encriptacion, configuracion, etc etc