2011-12-29 7 views
8

Tengo una pregunta con respecto a las siguientes llamadas a métodos:azúcar sintáctico genérico o verdadera mejora

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

Aquí es IL para estos dos llamadas:

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) 

Siempre he pensado en esta situación, el la versión genérica de este método fue más "azúcar sintáctico" vs. mejoría verdadera. ¿El IL dice una historia diferente?

Respuesta

8

Los genéricos están integrados en C#, por lo que es una "verdadera mejora". Por lo tanto, es posible la covarianza y contra varianza en tiempo de ejecución, así como la reflexión sobre tipos genéricos y la creación basada en la reflexión en tiempo de ejecución de tipos genéricos (como List<T> donde T se determina en tiempo de ejecución).

Esto difiere de C++, donde las plantillas son, de muchas maneras, azúcar sintáctico. El compilador realmente genera código para cada tipo genérico que use, por lo que Add<T> crearía Add<int>, Add<long>, Add<short>, Add<MyClass>, y así sucesivamente si estaba usando esas funciones, y lo mismo para las clases. El beneficio de esto son principalmente los operadores y algunas otras cosas más pequeñas: si cada uno de esos tipos tiene un operador + y Add<T>(T a, T b) devuelve a + b, todos los tipos funcionarán bien. El compilador de C# se quejaría porque no puede/no resuelve la declaración del operador para todos los tipos en el momento de la compilación. Además, C# (no 100% seguro, pero tal vez 90%) crea 1 implementación de tipo genérico para tipos de referencia (si está usando esa implementación) y luego 1 para cada tipo de valor (tan int, largo, Decimal, MyStruct, etc. obtener sus propias implementaciones, según sea necesario).

Cuestiones relacionadas