2011-12-29 14 views
8

Mam pytanie dotyczące następujących połączeń metoda:Generic cukier syntaktyczny lub prawdziwa poprawa

var ctl1 = this.FindControlRecursively("SomeField") as HiddenField; 
var ctl = this.FindControlRecursively<HiddenField>("SomeField"); 

Oto IL dla tych dwóch połączeń:

IL_0010: ldstr  "AsyncReset" 
IL_0015: call  class [System.Web]System.Web.UI.Control [Amc.WebG081.MethodExtensions]Amc.WebG081.ControlExtensions::FindControlRecursively(class [System.Web]System.Web.UI.Control,string) 

IL_001a: isinst  [System.Web]System.Web.UI.WebControls.HiddenField 
IL_001f: stloc.0 
IL_0020: ldarg.0 
IL_0021: ldstr  "AsyncReset" 
IL_0026: call  !!0 [Amc.WebG081.MethodExtensions]Amc.WebG081.ControlExtensions::FindControlRecursively<class [System.Web]System.Web.UI.WebControls.HiddenField>(class [System.Web]System.Web.UI.Control,string) 

Zawsze myślałem w tej sytuacji, ogólna wersja tej metody była bardziej "cukrem syntaktycznym" a prawdziwą poprawą. Czy IL opowiada inną historię?

Odpowiedz

8

Generics są wbudowane w C#, więc jest to "prawdziwa poprawa". Stąd też możliwe jest współzmienność i contra-wariancja w czasie pracy, a także refleksja nad rodzajami generycznymi i tworzeniem opartych na odbiciu generycznych typów (takich jak List<T>, gdzie T jest określane w czasie wykonywania).

Różni się od C++, gdzie szablony są pod wieloma względami cukrem syntaktycznym. Kompilator faktycznie generuje kod dla każdego generycznego typu, którego używasz - więc Add<T> utworzyłby Add<int>, Add<long>,, Add<MyClass> itd., Jeśli korzystałeś z tych funkcji, i podobnie dla klas. Zaletą tego są przede wszystkim operatorzy i kilka innych mniejszych rzeczy - jeśli każdy z tych typów ma operatora +, a Add<T>(T a, T b) zwraca a + b, wszystkie typy będą działały dobrze. Kompilator języka C# może narzekać, ponieważ nie może/nie rozpoznaje deklaracji operatora dla typów dowolnych podczas kompilacji. Co więcej, C# (nie 100% pewności, ale może 90%) tworzy 1 rodzajową implementację typów dla typów odniesienia (jeśli używasz tej implementacji), a następnie 1 dla każdego typu wartości (tak int, long, Decimal, MyStruct, etc all uzyskać własne implementacje, w razie potrzeby).

Powiązane problemy