例如,根据我的理解,此委托被缓存到单个实例并重用,因为它不会关闭任何局部变量:
int[] set = new [] { 1,2,3,4,5,6 };var subset = set.Where(x => x % 2 == 0);
现在我遇到一些情况,我生成的代码可能想直接调用委托,因此匿名方法无效C#,如下所示:
var result = (x => x % 2 == 0).Invoke(5); // InvalID
为了避免这种情况,我看到两个选择:
>使用构造函数:
var result = (new Func<int,bool>(x => x % 2 == 0)).Invoke(5);
>投射匿名代表:
var result = ((Func<int,bool>)(x => x % 2 == 0)).Invoke(5);
我假设编译器不会在选项#1中缓存委托,但我不确定它是否会在#2中.
这记录在哪里?
解决方法I’m assuming the compiler will not cache the delegate in option #1,but I’m not sure if it will in #2.
事实上,它可以在两种情况下,并且它们是捆绑在一起的.
从ECMA C#5规范,第7.6.10.5节:
The binding-time processing of a delegate-creation-Expression of the form new D(E),where D is a delegate-type and E is an Expression,consists of the following steps:
… If E is an anonymous function,the delegate creation Expression is processed in the same way as an anonymous function conversion (§6.5) from E to D. …
所以基本上两者都以同样的方式处理.在这两种情况下都可以缓存.是的,“新的并不一定意味着新的”是非常奇怪的.
为了表明这一点,让我们写一个非常简单的程序:
using System;public class Program{ public static voID Main() { var func = new Func<int,bool>(x => x % 2 == 0); }}
这是我的机器上的Main方法的IL(诚然使用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;}总结
以上是内存溢出为你收集整理的c# – 将强制类型委托的匿名lambda强制转换为禁用编译器缓存吗?全部内容,希望文章能够帮你解决c# – 将强制类型委托的匿名lambda强制转换为禁用编译器缓存吗?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)