Mnohé ze služeb platformy .NET (jako pozdní vazba, serializace, vzdálené řízení, atributy a podobně) závisejí na přítomnosti metadat. Vytvářené programy mohou využívat tato metadata a rozšiřovat je o nové informace. Reflexí je označováno prozkoumávání existujících typů prostřednictvím metadat. Uskutečňuje se prostřednictvím sady typů v oboru názvů System.Reflection. Je rovněž možné dynamicky vytvářet nové typy pomocí tříd v oboru názvů System.Reflection.Emit. Reflexe představuje procházení a manipulování s objektovým modelem, který představuje nějakou aplikaci včetně všech jejích elementů kompilace a běhu.
Základní jednotkou aplikace jsou její typy obsahující členy a vnořené typy. Typy jsou v modulech a ty obvykle v sestavách. Všechny tyto elementy jsou popsány metadaty. Za běhu jsou tyto elementy obsaženy uvnitř domény AppDomain.
Každý z prvků aplikace je vystaven prostřednictvím odpovídajícího typu z oboru názvů System nebo System.Reflection.
V okamžiku, kdy máte odkaz na některý z těchto elementů, můžete se pohybovat vztahy mezi daným elementem a souvisejícími prvky, jak je uvedeno na následujícím obrázku.
Třída Type je nejzákladnějším typem reflexe. Reprezentuje metadata pro jednotlivé deklarace typů v aplikaci. Typy obsahují členy. Ty zahrnují konstruktory, proměnné, vlastnosti, události a metody. Typy mohou navíc obsahovat vnořené typy, které se typicky používají jako pomocné třídy. Typy jsou seskupené do modulů a moduly jsou obsažené v sestavách.
Sestava je logickým ekvivalentem knihovny DLL v systému Win32 a je základní jednotkou zavádění, správy verzí a opakovaného používání typů
Modul je fyzický soubor (.exe, .dll), nebo nějaký prostředek (.gif, .jpg). Sestava může být tvořena několika moduly.
V jádru systému reflexe je System.Type, což je abstraktní bázová třída poskytující přístup k metadatům nějakého typu.
K instanci třídy Type lze přistoupit pomocí GetType(). Tato metoda je implementovaná v System.Object. Po zavolání vrátí metoda konkrétní typ System.Type, který dokáže typ reflektovat a manipulovat s ním.
Určitou třídu Type lze převzít pomocí názvu prostřednictvím statické metody GetType() ve třídě Type.
![]() | |
Type t = Type.GetType("System.Int32");
Type t2 = Type.GetType("MyNamespace.MyType", MyAssembly); | |
C# nabízí operátor typeof, který vrací třídu Type libovolného typu známého během kompilace.
![]() | |
Type t = typeof(System.Int32); | |
Rozdíl mezi těmito dvěma přístupy je, že přístup pomocí Type.GetType se vyhodnocuje za běhu, typeof se vyhodnocuje v době kompilace.
Máme-li instanci Type, můžeme přistupovat k metadatům prostřednictvím typů, jež představují členy, moduly, sestavy, třídy AppDomain a vnořené typy. lze zkoumat metadata, vlastní atributy, vytvářet nové instance typů a volat členy.
Příklad používá reflexi k zobrazení členů ve třech různých typech.
![]() | |
using System;
using System.Reflection;
class Test
{
static void Main()
{
object o = new Object();
Information(o.GetType());
Information(typeof(int));
Information(Type.GetType("System.String"));
}
static void Information(Type t)
{
Console.WriteLine("Type: {0}", t);
MemberInfo[] miarr = t.GetMembers();
foreach(MemberInfo mi in miarr)
Console.WriteLine(" {0}={1}", mi.MemberType, mi);
}
} | |
Je dynamické vytváření instancí a používání typů za běhu.
![]() | |
//Hello.cs
public abstract class Hello {
public abstrakt void SayHello();
} | |
![]() | |
//EnglishHello.cs
using System;
public class AmericanHello : Hello
{
private string message = "Hey Dude!";
public override void SayHello()
{
Console.WriteLine(message);
}
}
public class BritishHello : Pozdravy
{
private string message = "Hello!";
public override void SayHello()
{
Console.WriteLine(message);
}
} | |
![]() | |
//SayHello.cs
using System;
using System.Reflection;
class Test
{
static void Main()
{
string s = "EnglishHello.dll";
Assembly a = Assembly.LoadFrom(s);
foreach (Type t in a.getTypes())
{
if (t.IsSubClasOf(typeof(Hello))
{
object o = Activator.CreateInstance(t);
MethodInfo mi = t.GetMethod("SayHello");
mi.Invoke(o, null);
}
}
}
} | |
Podle řetězce s se nahraje EnglishHello.dll. Z jejich typů se vyhledá ten objekt, který má za předka třídu Hello a zajistí se nalezení metody SayHello. Metoda se vyvolá.
Obor názvů System.Reflection.Emit obsahuje třídy, které dokáží vytvořit za běhu úplně nové typy. Třídy umožňují:
definovat dynamickou sestavu v paměti;
definovat dynamický modul v této sestavě;
definovat nový typ v tomto modulu, včetně všech jeho členů;
vytvořit kódy MSIL potřebné k implementování aplikační logiky ve členech.


![[ukázka kódu]](images/tip.png)