2012-11-21 14 views
5

Capisco dalla documentazione di api che ReflectionOnlyGetType restituisce un tipo, molto simile a GetType. La differenza è che con ReflectionOnlyGetType, il tipo viene caricato solo per la reflection, non per l'esecuzione.ReflectionOnlyGetType vs GetType

Allora perché questo lavoro:

Type t = Type.ReflectionOnlyGetType("System.Collections.Generic.List`1[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", false, false); 
    ConstructorInfo[] cis = t.GetConstructors(); 
    foreach (ConstructorInfo ci in cis) 
    { 
     if (ci.GetParameters().Length == 0) 
     { 
      // ! no arg constructor found! let's call it! 
      Object o = ci.Invoke(new Object[]{}); 
      Console.WriteLine("But wait, it was supposed to be reflection only??"); 
      Console.WriteLine(o.GetType().Name); 
      List<String> lli = (List<String>)o; 
      lli.Add("but how can this be?"); 
      Console.WriteLine(lli.Count); 
      Console.WriteLine("I am doing a lot more than reflection here!"); 
     } 
    } 

La mia domanda è: mi sembra di essere in grado di fare di più che riflettere sui membri di questo tipo. Ho frainteso "esecuzione" quando dicono che il tipo è caricato "solo per riflessione, non per esecuzione"? Oppure ReflectionOnlyGetType restituisce un tipo diverso (non di sola riflessione) se il tipo era già "caricato" e qui è stato caricato in virtù dell'essere in mscorlib? O è qualcosa di completamente diverso?

+0

Naturalmente 'mscorlib' già inseriti per l'esecuzione dal runtime. –

+1

Se si desidera qualcosa che * garantirà * solo per la riflessione, IKVM.Reflection.dll può essere utile; questo è fondamentalmente un loader/parser completamente separato. –

risposta

3

Si sta caricando un tipo da mscorlib che è già stato caricato per l'esecuzione dal runtime. È possibile verificare la proprietà ReflectionOnly su un assieme per verificare se è stato caricato in un contesto ReflectionOnly. Nel tuo esempio,

Type t = Type.ReflectionOnlyGetType("System.Collections.Generic.List`1[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", false, false); 
Console.WriteLine(t.Assembly.ReflectionOnly); // prints False. 

Sembra che riflettere su mscorlib sia un po 'limitato. Da MSDN:

Non è possibile utilizzare il contesto di riflessione solo per caricare una versione di mscorlib.dll da una versione di .NET Framework diverso dalla versione nel contesto di esecuzione.

Suppongo che si estenda a caricare quello nel contesto di esecuzione corrente nel contesto di sola riflessione.

Sembra funzionare con altri assiemi BCL:

Console.WriteLine(Assembly.ReflectionOnlyLoad("System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089").ReflectionOnly); // prints True 
+0

Quasi capito ... significa che quando invochi GetType o ReflectionOnlyGetType, viene caricato il suo tipo più tutti gli altri tipi nel suo assembly definito? E a seconda di come hai caricato il tipo che determinerà se l'assemblaggio è caricato solo per il riflesso? Perché non esiste un flag di sola riflessione nei metodi Assembly.Load? – Mishax

+2

@Mishax Questi metodi 'GetType' causeranno il caricamento dell'assembly contenente nel contesto appropriato. Esistono metodi statici per caricare un assieme come solo per la riflessione: 'Assembly.ReflectionOnlyLoad' e' Assembly.ReflectionOnlyLoadFrom'. –

Problemi correlati