English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
La riflessione è la capacità del programma di accedere, rilevare e modificare lo stato o il comportamento di se stesso.
L'assembly contiene moduli, i moduli contengono tipi, e i tipi contengono membri. La riflessione fornisce oggetti per encapsulare assembly, moduli e tipi.
È possibile creare dinamicamente esempi di tipo utilizzando la riflessione, associare il tipo a un oggetto esistente o ottenere il tipo da un oggetto esistente. Poi, è possibile chiamare i metodi del tipo o accedere ai suoi campi e proprietà.
Vantaggi:
1. La riflessione migliora la flessibilità e l'estensibilità del programma.
2. Riduce la耦合 e migliora la capacità di adattamento.
3. Permette alla programma creare e controllare oggetti di qualsiasi classe, senza dover codificare il tipo di destinazione in anticipo.
Svantaggi:
1. Problemi di prestazioni: L'uso della riflessione è essenzialmente un'operazione di interpretazione, che è molto più lenta rispetto al codice diretto quando si accede ai campi e ai metodi. Pertanto, il meccanismo di riflessione viene principalmente applicato a sistemi di framework con elevati requisiti di flessibilità e espandibilità, e non si raccomanda l'uso in programmi normali.
2. L'uso della riflessione sfocchia la logica interna del programma; i programmatori desiderano vedere la logica del programma nel codice sorgente, ma la riflessione bypassa la tecnologia del codice sorgente, portando problemi di manutenzione. Il codice di riflessione è più complesso del codice diretto corrispondente.
La riflessione (Reflection) ha i seguenti scopi:
Permette di visualizzare le informazioni sulle caratteristiche (attribute) in tempo di esecuzione.
Permette di esaminare vari tipi nella raccolta e creare istanze di questi tipi.
Permette di associare metodi e proprietà (property) in modo differito.
Permette di creare nuovi tipi in tempo di esecuzione e poi eseguire alcune operazioni utilizzando questi tipi.
Abbiamo menzionato in precedenza in questo capitolo che è possibile visualizzare le informazioni sulle caratteristiche (attribute) utilizzando la riflessione (Reflection).
System.Reflection di classe MemberInfo L'oggetto deve essere inizializzato, utilizzato per trovare le caratteristiche (attribute) correlate alla classe. Per fare questo, è possibile definire un oggetto di classe di destinazione, come segue:
System.Reflection.MemberInfo info = typeof(MyClass);
Il seguente programma dimostra questo:
using System; [AttributeUsage(AttributeTargets.All)] public class HelpAttribute : System.Attribute { public readonly string Url; public string Topic // Topic è un parametro nominale { get { return topic; } set { topic = value; } } public HelpAttribute(string url) // url è un parametro posizionale { 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(); } } }
Quando il codice sopra viene compilato ed eseguito, mostra le caratteristiche aggiunte alla classe MyClass sulla caratteristica personalizzata:
HelpAttribute
In questo esempio, utilizzeremo l'oggetto creato nel capitolo precedente DeBugInfo caratteristiche, e utilizza la riflessione (Reflection) per leggerle Rectangle meta-dati della classe.
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 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); // Traverse Rectangle class attributes 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); } } // Traverse method attributes 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(); } } }
Quando il codice sopra è compilato ed eseguito, produce i seguenti risultati:
Length: 4.5 Width: 7.5 Area: 33.75 Bug No: 49 Developer: Nuha Ali Ultima revisione: 10/10/2012 Osservazioni: Variabile non utilizzata Numero di bug: 45 Sviluppatore: Zara Ali Ultima revisione: 12/8/2012 Osservazioni: Mismatch di tipo di ritorno Numero di bug: 55, per metodo: GetArea Sviluppatore: Zara Ali Ultima revisione: 19/10/2012 Osservazioni: Mismatch di tipo di ritorno Numero di bug: 56, per metodo: Display Sviluppatore: Zara Ali Ultima revisione: 19/10/2012 Osservazioni: