Reflection in C#
Inleiding
Het woord reflection komen we ook tegen in de term zelfreflectie. Bij zelfreflectie hou je jezelf een spiegel voor en je staat stil bij hoe je het gedaan hebt waarbij je tot de conclusie komt dat je het eigenlijk behoorlijk hebt vern**kt. Je had je nog beter kunnen inzetten voor den groote leijder en den glorieuze volkschgemeenschap, maar gelukkig komt er een volgende keer waarin je nog meer je best zal doen. Voor software hoeven we gelukkig niet zo diepzinnig te wezen. Men noemt de mogelijkheid om assemblies te doorzoeken Reflection en in deze post een voorbeeld hoe dat te doen.
GetExecutingAssembly
Met de System.Reflection namespace kunnen we bekijken (reflecteren) wat een assembly bevat en het onderstaande voorbeeldprogramma kijkt met GetExecutingAssembly naar de assembly die momenteel draait (m.a.w. het programma kijkt naar zichzelf). Het programma kijkt daarnaast met LoadFile naar een geslacht.dll assembly dat staat in folder C:\assemblies\
using System;
using System.Reflection;
namespace reflectieNameSpace
{
class ReflectieKlasse
{
static void Main(string[] args)
{
// GetExecutingAssembly
Assembly dezeAssembly = Assembly.GetExecutingAssembly();
Console.WriteLine("GetExecutingAssembly...");
Console.WriteLine("- " + dezeAssembly.Location);
foreach (Type t in dezeAssembly.GetTypes())
{
Console.WriteLine(
"- Name:" + t.Name + "\r\n" +
"- FullName:" + t.FullName + "\r\n" +
"- Type:" + t.GetType() + "\r\n");
}
// LoadFile
Assembly assemblyBestand =
Assembly.LoadFile("C:\\assemblies\\geslacht.dll");
Console.WriteLine("LoadFile(C:\\assemblies\\geslacht.dll)...");
Console.WriteLine("- FullName: " + assemblyBestand.FullName);
foreach (Type t in assemblyBestand.GetTypes())
{
Console.WriteLine(
"- Name:" + "" + t.Name + "\r\n" +
"- FullName:" + t.FullName + "\r\n" +
"- Type:" + t.GetType() + "\r\n");
}
// Gezien ?
Console.WriteLine("Gezien? Hit any key to continue.");
Console.ReadKey();
}
}
}
LoadFile
Met LoadFile wordt gekeken naar een assembly dat deze C# broncode bevat:
using System.Reflection;
[assembly: AssemblyTitle("geslacht")]
[assembly: AssemblyVersion("2.0.0.0")]
[assembly: AssemblyProduct("Library Bepaal Geslacht")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyDescription("Library om het geslacht te bepalen")]
namespace bibliotheek
{
public static class Geslacht
{
public static string Bepaal(char code, char codeHaarKleur)
{
string resultaat = "";
switch (code)
{
case 'M': resultaat = "Man ";break;
case 'V': resultaat = "Vrouw ";break;
case 'T': resultaat = "Transgender";break;
default: resultaat = "Onbekend";break;
}
switch (codeHaarKleur)
{
case 'A': resultaat = resultaat + "met blond haar.";break;
case 'B': resultaat = resultaat + "met bruin haar.";break;
case 'C': resultaat = resultaat + "met rood haar.";break;
case 'D': resultaat = resultaat + "met zwart haar.";break;
default: resultaat = resultaat + " met onbekende haarkleur";break;
}
return resultaat;
}
}
}
Resultaat
En onderstaand het resultaat van de reflectie. Het programma kijkt naar zichzelf met GetExecutingAssembly en het toont van zichzelf de naam van de aanwezige namespace en de naam van de aanwezige klasse. Het programma kijkt met LoadFile naar assembly C:\assemblies\geslacht.dll en het toont van die assembly o.a. de versie.
Interessant om te vermelden is dat we bij de reflectie resultaten van de .dll assembly bij de FullName interessante eigenschappen zien zoals een naam en een Version en een Culture en een PublicKeyToken. Het zijn de assembly eigenschappen waarmee een .dll assembly strong name gemaakt wordt. Zie verder deze post over wat strong named assemblies zijn.
Slot
Erg leuk zo’n (zelf)reflectie, maar waarom zou je in hemelsnaam in je eigen programma iets moeten programmeren waarmee je naar je naar eigen programma gaat kijken? Niet echt zinnig als je al weet wat je aan het doen bent en grip hebt op de situatie, maar stel dat een collega met de noorderzon vertrekt en jij zijn programmatuur in je maag krijgt gesplitst?
De documentatie, opgesteld in de taal van de Hunnen en voor het laatst bijgewerkt in 453 ad door Attila de Hun himself, geeft geen antwoord op al je vragen. Je inmiddels ex-collega heeft na het winnen van de staatsloterij de tijd van zijn leven met zijn 25 jaar jongere minnares op dat zeiljacht in Monaco en hij staat echt niet te wachten op een vraag van jou over meuk dat hij ooit eens in een vorig leven had gemaakt. Gelukkig hebben we de Reflection namespace waarmee we kunnen doorgronden wat de software van je, inmiddels ex-collega doet.
Hopelijk ben je met deze posting weer wat wijzer geworden en ik hoop je weer terug te zien in één van mijn volgende blog posts. Wil je weten wat ik nog meer over C# heb geschreven? Hit the C# button…