Reflexión
Objetos de reflexión se utilizan para la
obtención de información de tipo en tiempo de ejecución. Las clases que
dan acceso a los metadatos de un programa en ejecución se encuentran en el
espacio de nombres System.Reflection.
El espacio de nombres System.Reflection contiene
clases que permiten obtener información sobre la aplicación y agregar
dinámicamente tipos, valores y objetos de la aplicación.
Aplicaciones de
Reflexión
La reflexión tiene las siguientes aplicaciones:
·
Permite a la vista la información de atributos en
tiempo de ejecución.
·
Permite examinar diversos tipos en una asamblea y una
instancia de este tipo.
·
Se permite el enlace en tiempo a los métodos y
propiedades
·
Permite la creación de nuevos tipos en tiempo de
ejecución y luego realiza algunas tareas utilizando esos tipos.
Visualización de
metadatos
Ya hemos mencionado en el capítulo anterior que el uso
de la reflexión se puede ver la información de atributos.
El objeto de la
clase MemberInfo System.Reflection necesita ser inicializado
para descubrir los atributos asociados a una clase. Para ello, se define
un objeto de la clase de objetivos, como:
System.Reflection.MemberInfo
info = typeof(MyClass);
El programa siguiente muestra esto:
using System;
[AttributeUsage(AttributeTargets.All)]
public class
HelpAttribute : System.Attribute
{
public readonly string Url;
public string Topic // Topic is a named parameter
{
get
{
return topic;
}
set
{
topic = value;
}
}
public HelpAttribute(string url) // url is a positional parameter
{
this.Url = url;
}
private string topic;
}
[HelpAttribute("Information
on the class MyClass")]
class MyClass
{
}
namespace
AttributeAppl
{
class Program
{
static void Main(string[] args)
{
System.Reflection.MemberInfo info =
typeof(MyClass);
object[] attributes =
info.GetCustomAttributes(true);
for (int i = 0; i <
attributes.Length; i++)
{
System.Console.WriteLine(attributes[i]);
}
Console.ReadKey();
}
}
}
Cuando se compila y ejecutado, muestra el nombre de
los atributos especializado adjunto a la clase MiClase:
HelpAttribute
Ejemplo
En este ejemplo, utilizamos el
atributo debuginfo creado en el capítulo y el uso previo de reflexión
para leer los metadatos en la clase Rectangle.
using System;
using System.Reflection;
namespace
BugFixApplication
{
//a custom attribute BugFix to be
//assigned to a class and its members
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
public class DeBugInfo : System.Attribute
{
private int bugNo;
private string developer;
private string lastReview;
public string message;
public DeBugInfo(int bg, string dev,
string d)
{
this.bugNo = bg;
this.developer = dev;
this.lastReview = d;
}
public int BugNo
{
get
{
return bugNo;
}
}
public string Developer
{
get
{
return developer;
}
}
public string LastReview
{
get
{
return lastReview;
}
}
public string Message
{
get
{
return message;
}
set
{
message = value;
}
}
}
[DeBugInfo(45, "Zara Ali",
"12/8/2012", Message = "Return type mismatch")]
[DeBugInfo(49, "Nuha Ali",
"10/10/2012", Message = "Unused variable")]
class Rectangle
{
//member variables
protected double length;
protected double width;
public Rectangle(double l, double w)
{
length = l;
width = w;
}
[DeBugInfo(55, "Zara Ali",
"19/10/2012", Message = "Return type mismatch")]
public double GetArea()
{
return length * width;
}
[DeBugInfo(56, "Zara Ali",
"19/10/2012")]
public void Display()
{
Console.WriteLine("Length:
{0}", length);
Console.WriteLine("Width:
{0}", width);
Console.WriteLine("Area:
{0}", GetArea());
}
}//end class Rectangle
class ExecuteRectangle
{
static void Main(string[] args)
{
Rectangle r = new Rectangle(4.5, 7.5);
r.Display();
Type type = typeof(Rectangle);
//iterating through the attribtues of
the Rectangle class
foreach (Object attributes in
type.GetCustomAttributes(false))
{
DeBugInfo dbi =
(DeBugInfo)attributes;
if (null != dbi)
{
Console.WriteLine("Bug no: {0}",
dbi.BugNo);
Console.WriteLine("Developer: {0}", dbi.Developer);
Console.WriteLine("Last
Reviewed: {0}", dbi.LastReview);
Console.WriteLine("Remarks:
{0}", dbi.Message);
}
}
//iterating through the method
attribtues
foreach (MethodInfo m in
type.GetMethods())
{
foreach (Attribute a in
m.GetCustomAttributes(true))
{
DeBugInfo dbi = (DeBugInfo)a;
if (null != dbi)
{
Console.WriteLine("Bug
no: {0}, for Method: {1}", dbi.BugNo, m.Name);
Console.WriteLine("Developer: {0}", dbi.Developer);
Console.WriteLine("Last
Reviewed: {0}", dbi.LastReview);
Console.WriteLine("Remarks:
{0}", dbi.Message);
}
}
}
Console.ReadLine();
}
}
}
Cuando el código se compila y ejecuta, se produce el
siguiente resultado:
Length: 4.5
Width: 7.5
Area: 33.75
Bug No: 49
Developer:
Nuha Ali
Last
Reviewed: 10/10/2012
Remarks:
Unused variable
Bug No: 45
Developer:
Zara Ali
Last
Reviewed: 12/8/2012
Remarks: Return type mismatch
Bug No: 55,
for Method: GetArea
Developer:
Zara Ali
Last
Reviewed: 19/10/2012
Remarks:
Return type mismatch
Bug No: 56,
for Method: Display
Developer:
Zara Ali
Last Reviewed: 19/10/2012
Remarks:
DEMOSTRACIÓN
En Visual Studio vamos a dar click en menú File à New à Project
En la Ventana emergente le damos click a Window, seleccionamos la opción “Console Application” y espacio Name colocamos el nombre del proyecto que para el Ejemplo es “Demo 12 20483” y luego presionamos el botón OK.
Haremos primero un llamado de referencias a refection
En el editor de código arriba del método Main() vamos
a crear una clase denominada ‘Cuenta’
Posteriormente en el método Main() codificaremos lo
siguiente:
Ejecutamos
Y la salida por pantalla sería la siguiente: