1 回答
TA贡献1842条经验 获得超22个赞
我假设编译器不会在选项 #1 中缓存委托,但我不确定它是否会在 #2 中缓存。
事实上,在这两种情况下都可以,而且它们是捆绑在一起的。
来自 ECMA C# 5 规范,第 7.6.10.5 节:
new D(E) 形式的委托创建表达式(其中 D 是委托类型,E 是表达式)的绑定时处理包括以下步骤:
...
如果 E 是匿名函数,则委托创建表达式的处理方式与从 E 到 D 的匿名函数转换(第 6.5 节)相同。
...
所以基本上两者的处理方式相同。在这两种情况下,它都可以被缓存。是的,“新并不一定意味着新”是很奇怪的。
为了说明这一点,让我们编写一个非常简单的程序:
using System;
public class Program
{
public static void Main()
{
var func = new Func<int, bool>(x => x % 2 == 0);
}
}
这是我机器上的方法的 IL Main(诚然是使用 C# 8 预览版编译器构建的,但我希望在一段时间内也是如此):
.method public hidebysig static void Main() cil managed
{
.entrypoint
// Code size 29 (0x1d)
.maxstack 8
IL_0000: ldsfld class [mscorlib]System.Func`2<int32,bool> Program/'<>c'::'<>9__0_0'
IL_0005: brtrue.s IL_001c
IL_0007: ldsfld class Program/'<>c' Program/'<>c'::'<>9'
IL_000c: ldftn instance bool Program/'<>c'::'<Main>b__0_0'(int32)
IL_0012: newobj instance void class [mscorlib]System.Func`2<int32,bool>::.ctor(object,
native int)
IL_0017: stsfld class [mscorlib]System.Func`2<int32,bool> Program/'<>c'::'<>9__0_0'
IL_001c: ret
} // end of method Program::Main
这是有效的:
Func<int, bool> func;
func = cache;
if (func == null)
{
func = new Func<int, bool>(GeneratedPrivateMethod);
cache = func;
}
- 1 回答
- 0 关注
- 140 浏览
添加回答
举报
