通用语法糖或真正的改进

Pat*_*ley 8 c# asp.net generics il

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

var ctl1 = this.FindControlRecursively("SomeField") as HiddenField;
var ctl = this.FindControlRecursively<HiddenField>("SomeField");
Run Code Online (Sandbox Code Playgroud)

这是这两个电话的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)
Run Code Online (Sandbox Code Playgroud)

我一直认为在这种情况下,这种方法的通用版本更像是"语法糖"而不是真正的改进.IL讲的是另一个故事吗?

GGu*_*ati 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等全部根据需要获得自己的实现.