Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Industrial programming >> C Taal

C# Reflectie onder de knie: runtime-typeontdekking en dynamische programmering

Reflectie-objecten worden gebruikt om type-informatie tijdens runtime op te halen. De klassen die toegang bieden tot de metadata van een draaiend programma, bevinden zich in de System.Reflection-naamruimte.

De System.Reflection-naamruimte bevat klassen waarmee u informatie over de applicatie kunt verkrijgen en dynamisch typen, waarden en objecten aan de applicatie kunt toevoegen.

Toepassingen van Reflectie

Reflectie heeft de volgende toepassingen:

  • Het maakt het mogelijk attribuutinformatie tijdens runtime te bekijken.

  • Het stelt het bestuderen van verschillende typen in een assembly en het instantiëren ervan toe.

  • Het maakt late binding aan methoden en eigenschappen mogelijk.

  • Het maakt het aanmaken van nieuwe typen tijdens runtime en het uitvoeren van taken met die typen mogelijk.

Metadata bekijken

In het voorgaande hoofdstuk hebben we aangegeven dat u met reflectie attribuutinformatie kunt bekijken.

Het MemberInfo-object van de System.Reflection-klasse moet geïnitialiseerd worden om de attributen te ontdekken die aan een klasse zijn gekoppeld. Hiervoor definieert u een object van de doelklasse als volgt:

System.Reflection.MemberInfo info = typeof(MyClass);

Het volgende programma demonstreert dit:

using System;

[AttributeUsage(AttributeTargets.All)]
public class HelpAttribute : System.Attribute {
    public readonly string Url;
    public string Topic { // Topic is een benoemde parameter
        get { return topic; }
        set { topic = value; }
    }
    public HelpAttribute(string url) { // url is een positionele parameter
        this.Url = url;
    }
    private string topic;
}

[HelpAttribute("Informatie over de klasse 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();
        }
    }
}

Wanneer het gecompileerd en uitgevoerd wordt, toont het de naam van de aangepaste attributen die aan de klasse MyClass zijn gekoppeld:

HelpAttribute

Voorbeeld

In dit voorbeeld gebruiken we het DeBugInfo-attribuut dat in het vorige hoofdstuk is gemaakt en gebruiken reflectie om metadata in de Rectangle-klasse uit te lezen.

Live Demo
using System;
using System.Reflection;

namespace BugFixApplication {
    // een aangepast attribuut BugFix dat aan een klasse en zijn leden toegewezen kan worden
    [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 {
        // lidvariabelen
        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());
        }
    } // einde klasse Rectangle

    class ExecuteRectangle {
        static void Main(string[] args) {
            Rectangle r = new Rectangle(4.5, 7.5);
            r.Display();

            Type type = typeof(Rectangle);
            // itereren door de attributen van de Rectangle-klasse
            foreach (Object attributes in type.GetCustomAttributes(false)) {
                DeBugInfo dbi = (DeBugInfo)attributes;
                if (null != dbi) {
                    Console.WriteLine("Bug nr: {0}", dbi.BugNo);
                    Console.WriteLine("Ontwikkelaar: {0}", dbi.Developer);
                    Console.WriteLine("Laatst bekeken: {0}", dbi.LastReview);
                    Console.WriteLine("Opmerkingen: {0}", dbi.Message);
                }
            }

            // itereren door de methode-attributen
            foreach (MethodInfo m in type.GetMethods()) {
                foreach (Attribute a in m.GetCustomAttributes(true)) {
                    DeBugInfo dbi = (DeBugInfo)a;
                    if (null != dbi) {
                        Console.WriteLine("Bug nr: {0}, voor Methode: {1}", dbi.BugNo, m.Name);
                        Console.WriteLine("Ontwikkelaar: {0}", dbi.Developer);
                        Console.WriteLine("Laatst bekeken: {0}", dbi.LastReview);
                        Console.WriteLine("Opmerkingen: {0}", dbi.Message);
                    }
                }
            }
            Console.ReadLine();
        }
    }
}

Wanneer de bovenstaande code wordt gecompileerd en uitgevoerd, produceert het het volgende resultaat:

Length: 4.5
Width: 7.5
Area: 33.75
Bug nr: 49
Ontwikkelaar: Nuha Ali
Laatst bekeken: 10/10/2012
Opmerkingen: Unused variable
Bug nr: 45
Ontwikkelaar: Zara Ali
Laatst bekeken: 12/8/2012
Opmerkingen: Return type mismatch
Bug nr: 55, voor Methode: GetArea
Ontwikkelaar: Zara Ali
Laatst bekeken: 19/10/2012
Opmerkingen: Return type mismatch
Bug nr: 56, voor Methode: Display
Ontwikkelaar: Zara Ali
Laatst bekeken: 19/10/2012
Opmerkingen: 

C Taal

  1. C# Hello World – Uw eerste C# applicatie bouwen
  2. C# Keywords en Identifiers begrijpen: Regels, lijsten en best practices
  3. C# Variabelen & Primitive Datatypes onder de knie krijgen: Complete gids
  4. C# Operators – Uitgebreide gids voor operators in C#
  5. C# Bitwise en Bit Shift Operators: Een Uitgebreide Gids
  6. C# Fundamentals: Invoer en Uitvoer Basis
  7. C# Expressies, Statements & Blokken: Uitgebreide Gids met Praktische Voorbeelden
  8. C# Comments Onder de Loep: Types, Best Practices en XML Documentatie
  9. C# Break Statement: Hoe en Wanneer Te Gebruiken
  10. C# Continue Statement: Effectief Lusiteraties Overslaan
  11. C# Arrays: Declaratie, Initialisatie en Operaties