English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
La reflexión es la capacidad de un programa para acceder, detectar y modificar su propio estado o comportamiento.
El ensamblaje contiene módulos, los módulos contienen tipos y los tipos contienen miembros. La reflexión proporciona objetos que encapsulan ensamblajes, módulos y tipos.
Puede usar la reflexión para crear ejemplos dinámicamente de tipos, vincular tipos a objetos existentes o obtener tipos de objetos existentes. Luego, puede llamar a los métodos del tipo o acceder a sus campos y propiedades.
Ventajas:
1、La reflexión mejora la flexibilidad y la expansibilidad del programa.
2、Reduce la耦合 y mejora la capacidad de adaptación.
3、Permite que el programa cree y controle objetos de cualquier clase sin necesidad de codificar previamente la clase objetivo.
Desventajas:
1、Problemas de rendimiento: El uso de la reflexión es básicamente una operación de interpretación, que es mucho más lenta que el código directo al acceder a campos y métodos. Por lo tanto, el mecanismo de reflexión se aplica principalmente en marcos de sistemas que requieren alta flexibilidad y expansibilidad, y no se recomienda su uso en programas comunes.
2、El uso de la reflexión puede desdibujar la lógica interna del programa; los programadores desean ver la lógica del programa en el código fuente, pero la reflexión evita el código fuente técnico, lo que puede causar problemas de mantenimiento, y el código de reflexión es más complejo que el código directo correspondiente.
La reflexión (Reflection) tiene los siguientes usos:
Permite ver la información de las características (attributes) en tiempo de ejecución.
Permite examinar varios tipos en una colección y ejemploizar estos tipos.
Permite la vinculación diferida de métodos y propiedades (properties).
Permite crear nuevos tipos en tiempo de ejecución y luego ejecutar tareas con estos tipos.
Hemos mencionado en el capítulo anterior que se puede ver la información de las características (attributes) utilizando la reflexión (Reflection).
System.Reflection de la clase MemberInfo Los objetos necesitan ser inicializados para descubrir las características relacionadas con la clase. Para lograr esto, puede definir un objeto de la clase objetivo, como se muestra a continuación:
System.Reflection.MemberInfo info = typeof(MyClass);
El siguiente programa demuestra esto:
using System; [AttributeUsage(AttributeTargets.All)] public class HelpAttribute : System.Attribute { public readonly string Url; public string Topic // Topic es un parámetro nombrado { get { return topic; } set { topic = value; } } public HelpAttribute(string url) // url es un parámetro posicional { this.Url = url; } private string topic; } [HelpAttribute("Información sobre la clase 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 el código anterior se compila y ejecuta, muestra las características adicionadas a la clase MyClass la característica personalizada:
HelpAttribute
En este ejemplo, utilizaremos el que se creó en el capítulo anterior DeBugInfo 特性,并使用反射(Reflection)来读取 Rectangle 类中的元数据。
using System; using System.Reflection; namespace BugFixApplication { // 一个自定义特性 BugFix 被赋给类及其成员 [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 { // 成员变量 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 longitud * ancho; } [DeBugInfo(56, "Zara Ali", "19/10/2012) public void Display() { Console.WriteLine("Longitud: {0}", longitud); Console.WriteLine("Ancho: {0}", ancho); Console.WriteLine("Área: {0}", GetArea()); } }//fin de clase Rectangle class ExecuteRectangle { static void Main(string[] args) { Rectangle r = new Rectangle(4.5, 7.5); r.Display(); Type type = typeof(Rectangle); // Recorrer las características de la clase Rectangle foreach (Object attributes in type.GetCustomAttributes(false)) { DeBugInfo dbi = (DeBugInfo)attributes; if (null != dbi) { Console.WriteLine("Número de error: {0}", dbi.NúmeroError); Console.WriteLine("Desarrollador: {0}", dbi.Desarrollador); Console.WriteLine("Última revisión: {0}", dbi.UltimaRevisión); Console.WriteLine("Observaciones: {0}", dbi.Mensaje); } } // Recorrer las características del método foreach (MethodInfo m in type.GetMethods()) { foreach (Attribute a in m.GetCustomAttributes(true)) { DeBugInfo dbi = (DeBugInfo)a; if (null != dbi) { Console.WriteLine("Número de error: {0}, para el método: {1}", dbi.NúmeroError, m.Nombre); Console.WriteLine("Desarrollador: {0}", dbi.Desarrollador); Console.WriteLine("Última revisión: {0}", dbi.UltimaRevisión); Console.WriteLine("Observaciones: {0}", dbi.Mensaje); } } } Console.ReadLine(); } } }
Cuando el código superior se compila y ejecuta, se producirá el siguiente resultado:
Longitud: 4.5 Ancho: 7.5 Área: 33.75 Número de error: 49 Desarrollador: Nuha Ali Última revisión: 10/10/2012 Comentarios: Variable no utilizada Número de error: 45 Desarrollador: Zara Ali Última revisión: 12/8/2012 Comentarios: Desajuste de tipo de retorno Número de error: 55, para Método: GetArea Desarrollador: Zara Ali Última revisión: 19/10/2012 Comentarios: Desajuste de tipo de retorno Número de error: 56, para Método: Display Desarrollador: Zara Ali Última revisión: 19/10/2012 Comentarios: