通用的语法糖还是真正的改进?

8

我有一个关于以下方法调用的问题:

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个回答

8

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

这与C++不同,其中模板在很多方面都是语法糖。编译器实际上会为您使用的每个泛型类型生成代码 - 因此如果您在使用这些函数,Add<T> 将创建 Add<int>Add<long>Add<short>Add<MyClass> 等等,类似地对于类也是如此。这主要有利于操作符和其他一些较小的东西 - 如果每个类型都有一个 + 操作符,并且 Add<T>(T a, T b) 返回 a + b,那么所有类型都可以正常工作。C# 的编译器会抱怨,因为它无法在编译时解析任何类型的操作符声明。此外,C#(不确定是否完全,但可能有 90%)为引用类型创建 1 个泛型类型实现,然后为每个值类型(因此 int、long、Decimal、MyStruct 等都会根据需要获得自己的实现)创建 1 个泛型类型实现。


2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接