Ho giocato con alcune affermazioni C# in LINQPad allo scopo di comprendere quale codice di lingua intermedio viene emesso.Il tipo dinamico C# fa sì che Console.WriteLine venga risolto con il riflesso in IL
ho provato il seguente codice:
var Container = new {Name = "James"};
Console.WriteLine(Container.Name);
e vide le seguenti sei linee di IL emessi:
IL_0001: ldstr "James"
IL_0006: newobj <>f__AnonymousType0<System.String>..ctor
IL_000B: stloc.0
IL_000C: ldloc.0
IL_000D: callvirt <>f__AnonymousType0<System.String>.get_Name
IL_0012: call System.Console.WriteLine
Il che, è sostanzialmente quello che mi aspetto, ed è piuttosto una bella dimostrazione di in che modo i tipi anonimi sono di sola lettura/immutabili, poiché non esiste una proprietà set_Name.
Poi ho provato le dichiarazioni:
dynamic Container = new System.Dynamic.ExpandoObject();
Container.Name = "James";
Console.WriteLine(Container.Name);
che causa una quantità enorme di IL essere emessi. Non lo incollo qui, ma puoi trovarlo in this pastebin.
Capisco che c'è un po 'di overhead per quanto riguarda la gestione del tipo dinamico e ExpandoObject, ma non capisco perché sembra che la chiamata a System.Console.WriteLine
sia in questo caso eseguita tramite riflessione interna.
IL_0072: ldstr "WriteLine"
....
IL_00BF: ldtoken System.Console
Nel primo segmento di codice, dopo che la proprietà è stato recuperato e conservato, è stata una IL dichiarazione di una linea che ha richiamato System.Console.WriteLine
.
Quindi perché tutto questo extra è necessario per la chiamata con un tipo dynamic
?
In realtà, il trucco 'ToString()' non funzionerà (a meno che non si aggiunga un cast esplicito a 'string'). – svick
@svick Si è corretto, aggiornato di conseguenza. – Servy