通用语法糖或真正的改进

时间:2011-12-29 20:24:33

标签: c# asp.net generics il

我对以下方法调用有疑问:

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

以下是这两个电话的IL:

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)

我一直认为在这种情况下,这种方法的通用版本更具“语法糖”而不是真正的改进。 IL会讲一个不同的故事吗?

2 个答案:

答案 0 :(得分:8)

泛型内置于C#中,因此它是一种“真正的改进”。因此,为什么运行时协方差和反方差是可能的,以及对泛型类型的反射和基于运行时反射的泛型类型的创建(例如List<T>,其中T在运行时确定)

这不同于C ++,其中模板在很多方面都是语法糖。编译器实际上为您使用的每个泛型类型生成代码 - 因此Add<T>会创建Add<int>Add<long>Add<short>Add<MyClass>等等,如果您是使用这些功能,同样适用于类。这样做的好处主要是运算符和一些其他较小的东西 - 如果每个类型都有一个+运算符,Add<T>(T a, T b)返回一个+ b,所有类型都可以正常工作。 C#的编译器会抱怨,因为它不能/不能在编译时解析任何类型的运算符声明。此外,C#(不是100%肯定,但可能是90%)为引用类型(如果您正在使用该实现)创建1个泛型类型实现,然后为每个值类型创建1(所以int,long,Decimal,MyStruct等全部根据需要获得自己的实现。

答案 1 :(得分:2)

在java中,泛型是语法糖,但在c#中,它们是内置的。看看这个: www.25hoursaday.com/CsharpVsJava.html