如果可用,使用C#方法组有什么好处吗?
处理List
类的东西时,您可以编写以下内容:
list.ForEach(x => Console.WriteLine(x));
或者您可以使用方法组执行相同的操作:
list.ForEach(Console.WriteLine);
我更喜欢第二行代码,因为它对我来说看起来更干净,但这有什么好处吗?
好吧,让我们来看看会发生什么。
static void MethodGroup() { new List().ForEach(Console.WriteLine); } static void LambdaExpression() { new List ().ForEach(x => Console.WriteLine(x)); }
这将编译成以下IL。
.method private hidebysig static void MethodGroup() cil managed { .maxstack 8 L_0000: newobj instance void [mscorlib]System.Collections.Generic.List`1::.ctor() L_0005: ldnull L_0006: ldftn void [mscorlib]System.Console::WriteLine(string) L_000c: newobj instance void [mscorlib]System.Action`1 ::.ctor(object, native int) L_0011: call instance void [mscorlib]System.Collections.Generic.List`1 ::ForEach(class [mscorlib]System.Action`1) L_0016: ret } .method private hidebysig static void LambdaExpression() cil managed { .maxstack 8 L_0000: newobj instance void [mscorlib]System.Collections.Generic.List`1 ::.ctor() L_0005: ldsfld class [mscorlib]System.Action`1 Sandbox.Program::CS$<>9__CachedAnonymousMethodDelegate1 L_000a: brtrue.s L_001d L_000c: ldnull L_000d: ldftn void Sandbox.Program::b__0(string) L_0013: newobj instance void [mscorlib]System.Action`1::.ctor(object, native int) L_0018: stsfld class [mscorlib]System.Action`1 Sandbox.Program::CS$<>9__CachedAnonymousMethodDelegate1 L_001d: ldsfld class [mscorlib]System.Action`1 Sandbox.Program::CS$<>9__CachedAnonymousMethodDelegate1 L_0022: call instance void [mscorlib]System.Collections.Generic.List`1 ::ForEach(class [mscorlib]System.Action`1) L_0027: ret }
注意方法组方法如何为一次性使用创建Action
委托,lambda表达式方法创建隐藏的匿名委托字段,并在必要时对其进行内联初始化。 注意brtrue
指令。
使用lambda表达式时有一个额外的间接级别。 使用像这样的非闭包表达式,您只需在其他方法中间进行额外的方法调用。
但是有一些有趣的差异。 在第二种情况下,每次调用都会创建一个新的委托实例。 对于前者,委托创建一次并缓存为隐藏字段,因此如果您要调用很多,则可以节省分配。
此外,如果将局部变量引入lambda表达式,它将成为闭包,而不是仅生成本地方法,将创建一个新类来保存此信息,这意味着在那里进行额外分配。
正如其他人所指出的那样,由lambda引起的额外不必要的间接层。 但是,语言也存在细微差别。 例如,在C#3中,当尝试执行返回类型推断时,generics类型推断在M(F)
与在M(x=>F(x))
上的工作方式不同。
详情见:
https://blogs.msdn.com/b/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx
和后续行动:
https://blogs.msdn.com/b/ericlippert/archive/2008/05/28/method-type-inference-changes-part-zero.aspx
我相信有一个好处。 在第一种情况下,您正在创建一个调用Console.Writeline(string)
函数的匿名方法,而在另一种情况下,您只是将引用传递给现有函数。
是; 第一个实际上可以导致不必要的额外临时呼叫发生; 将x
传递给一个简单地调用Console.WriteLine(x);
您不需要执行第一个,因为Console.WriteLine已经是一个与ForEach正在查找的签名匹配的方法。
我个人也更喜欢第二种,因为调试起来不那么混乱,但在这种情况下,我认为这只是风格问题,因为它们最终都会完成同样的事情。
没有任何实际的好处,除了让那些喜欢方法组的人更加愉快,并且惹恼那些不喜欢他们的人[应该让你高兴。]此外,它使你的代码与早期的编译器不兼容。
-Oisin
上述就是C#学习教程:如果可用,使用C#方法组有什么好处吗?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1008963.html