Sep.12

Reflection

Wat is reflection?
Reflection maakt het mogelijk dat een programma zijn eigen structuur kan bekijken en zo mogelijk aanpassen.

Reflection is een onderdeel van het .NET framework (via de System.Reflection namespace). Met behulp van reflection kunnen we tijdens runtime programma-klassen bekijken, objecten instantieren, waarden wijzigen etc…

Het nut van reflection is bijvoorbeeld dat er gemakkelijker generieke code kan worden geschreven. Met behulp van reflection kan bijv. voor onderstaande of soortgelijke klassen SQL queries worden opgebouwd die de alle noodzakelijke communicatie naar een willekeurig DBMS mogelijk maken. Dit hoeft dan niet meer per klasse te gebeuren. NHibernate is een goed voorbeeld van gebruik van o.a. reflection.

Aan de hand van onderstaande klasse wil ik laten zien hoe het een ander met behulp van reflection gedaan kan worden.
Persoon.cs

De System.Type klasse is zo’n beetje de belangrijkste bij het gebruik van reflection. Om aan een System.Type instantie te komen kan op een instantie van een klasse (object) de .GetType() methode worden aangeroepen. Is er geen instantie beschikbaar dan kan doormiddel van typeof(..) functie het System.Type van een bepaald type worden opgevraagd.

Nu een System.Type ter beschikking staat kunnen gegevens worden opgevraagd, bijvoorbeeld:

resulteert in:

Name : Persoon
FullName : snoei.net.test.Persoon
Module.FullyQualifiedName : C:WINDOWSMicrosoft.NETFrameworkv2.0.50727Temporary ASP.NET Filesprostat124b611274f8497bApp_Code.jtzqqm81.dll
Namespace : snoei.net.test
UnderlayingSystemType : snoei.net.test.Persoon

Properties
De properties van de Persoon klasse kunnen alsvolgt worden uitgevraagd:

Deze retourneert een array met PropertyInfo objecten. Het PropertyInfo object beschrijft een property.
Met de volgende code kunnen we propertyinformatie ophalen:

Het resultaat:

Middels het PropertyInfo object is het mogelijk propertygegevens te lezen en te schrijven voor een bepaalde Persoon instantie.

  • Op regel 1-4 wordt een Persoon object gecreeerd.
  • Op regel 5 vragen wordt het System.Type opgevraagd van het type Persoon.

    zou in hetzelfde resulteren.

  • Op regel 6 wordt het PropertyInfo object opgehaald voor de property “Voornaam” van het System.Type Persoon (PersoonType).
  • Op regel 7 wordt er voor de instantie p van Persoon de waarde van de Voornaam property opgevraagd.
  • Op regel 9 wordt er een waarde gezet in de Voornaam property van object p.
  • Dit resulteert in het volgende:

    Methoden
    Naast het uitvragen van properties kunnen ook methodes worden uitgevoerd. Doormiddel van de functie PersoonType.GetMethods() kunnen we gegevens van alle methoden opvragen. Deze functie retourneert een array van MethodInfo objecten.
    Het persoon object heeft een methode “GetFullname”. Met behulp van de volgende code roepen we deze methode aan:

    Met behulp van de Invoke functie kan de methode worden aangeroepen. Het betrokken object moet worden meegegeven in het geval het niet om een static method gaat. Gaat het om een static method dan wordt dan ziet de invoke er alsvolgt uit:

    Aangezien de methode geen parameters heeft wordt een lege object array meegegeven. Mochten de methode parameters bevatten dan kunnen de mee te geven waarden (in de juiste volgorde) in de object array worden geplaatst. Stel dat we een GetFullname methode hebben die een string verwacht waarmee titel kan worden gezet dan ziet de code er alsvolgt uit:

    Instantiatie
    Er is uiteraard nog veel meer mogelijk met reflection. Maar voor nu wil ik alleen nog even laten zien hoe er een instantie van een klasse kan worden gemaakt via reflection. Dus het maken van een instantie van de Persoon klasse in runtime:

    Conclusie
    Dat is reflection in het kort. In veel gevallen kan het gebruik van reflection zaken generieker maken en maakt oplossingen met minder code mogelijk. Reflection is een redelijk alternatief voor codegeneratie. Dat wil echter niet zeggen dat codegeneratie in alle gevallen vervangen kan worden door reflection te gebruiken. Een nadeel van reflection is het ten koste gaat van enige performance. De performance is echter voor veel toepassingen ruim toereikend en dan hoeft het geen belemmering te zijn.

    Deel dit Verhaal:
    • facebook
    • twitter
    • gplus

    Over Ton Snoei

    Een enthousiaste ontwikkelaar in de allerbreedste zin van het woord.

    Het aansturen maar vooral coachen van mensen geeft me veel plezier en een leuke uitdaging. Ik houdt me graag bezig met het bouwen van software maar ook met alle anderen dingen die komen kijken bij het vak dat IT heet.

    Met als achtergrond ontwikkelaar heb ik veel ervaring met C# .NET en alles wat daarbij komt kijken. Deze kennis komt nog regelmatig goed van pas. Mijn liefde voor ontwikkeling van software is nooit verdwenen en heb mij daarom in het afgelopen jaar meer verdiept in Java, Android, iOS/iPhone/iPad (Monotouch/Xamarin), PHP en Unity 3D development. Ik noem dat altijd maar: "Lego-spelen voor grote mensen" ;-)

    Kortom van de grote lijnen naar projecten tot hands-on problem solven.

    Reacties(2)

    1. P.J. van de Sande
      5264 days geleden

      Het belangrijkste vergeet je imho, Attributes. Deze worden veel gebruikt en dienen uitgelezen te worden met reflecten.

      Volgende post over IL Emitting? 🙂

    2. tsnoei
      5264 days geleden

      Tja, je hebt gelijk, dat had er nog wel bij gemogen.

      IL emitting is wel een vak apart ik heb daar eerlijk gezegd nog niet zo heel veel mee gedaan.

    Laat een reactie achter

    Comment