c# – 离散匿名方法共享一个类?

c# – 离散匿名方法共享一个类?,第1张

概述我正在和Eric Lippert的Ref< T>类从 here.我在IL中注意到,看起来两个匿名方法都使用相同的生成的类,即使这意味着该类有一个额外的变量. 虽然只使用一个新的类定义似乎有些合理,但是它使我非常奇怪,只创建了一个“c__DisplayClass2”实例.这似乎意味着Ref< T>的两个实例正在引用相同的c_DisplayClass2这不意味着在收集vart1之前不能收集y,这可能比 我正在和Eric lippert的Ref< T>类从 here.我在IL中注意到,看起来两个匿名方法都使用相同的生成的类,即使这意味着该类有一个额外的变量.

虽然只使用一个新的类定义似乎有些合理,但是它使我非常奇怪,只创建了一个“c__displayClass2”实例.这似乎意味着Ref< T>的两个实例正在引用相同的c_displayClass2这不意味着在收集vart1之前不能收集y,这可能比joik返回后更晚?毕竟,不能保证一些白痴不会写一个函数(直接在IL中),它直接通过vart1 aftrer joik返回访问y.也许这甚至可以通过反思而不是通过疯狂的IL来完成.

sealed class Ref<T>{    public delegate T Func<T>();    private Readonly Func<T> getter;    public Ref(Func<T> getter)    {        this.getter = getter;    }    public T Value { get { return getter(); } }}static Ref<int> joik(){    int[] y = new int[50000];    int x = 5;    Ref<int> vart1 = new Ref<int>(delegate() { return x; });    Ref<int[]> vart2 = new Ref<int[]>(delegate() { return y; });    return vart1;}

运行IL DASM证实vart1和vart2都使用了__ displayClass2,它包含x和y的公共字段. joik的IL

.method private hIDebysig static class Program/Ref`1<int32>         joik() cil managed{  // Code size       72 (0x48)  .maxstack  3  .locals init ([0] class Program/Ref`1<int32> vart1,[1] class Program/Ref`1<int32[]> vart2,[2] class Program/'<>c__displayClass2' '<>8__locals3',[3] class Program/Ref`1<int32> CS00)  IL_0000:  newobj     instance voID Program/'<>c__displayClass2'::.ctor()  IL_0005:  stloc.2  IL_0006:  nop  IL_0007:  ldloc.2  IL_0008:  ldc.i4     0xc350  IL_000d:  newarr     [mscorlib]system.int32  IL_0012:  stfld      int32[] Program/'<>c__displayClass2'::y  IL_0017:  ldloc.2  IL_0018:  ldc.i4.5  IL_0019:  stfld      int32 Program/'<>c__displayClass2'::x  IL_001e:  ldloc.2  IL_001f:  ldftn      instance int32 Program/'<>c__displayClass2'::'<joik>b__0'()  IL_0025:  newobj     instance voID class Program/Ref`1/Func`1<int32,int32>::.ctor(object,native int)  IL_002a:  newobj     instance voID class Program/Ref`1<int32>::.ctor(class Program/Ref`1/Func`1<!0,!0>)  IL_002f:  stloc.0  IL_0030:  ldloc.2  IL_0031:  ldftn      instance int32[] Program/'<>c__displayClass2'::'<joik>b__1'()  IL_0037:  newobj     instance voID class Program/Ref`1/Func`1<int32[],int32[]>::.ctor(object,native int)  IL_003c:  newobj     instance voID class Program/Ref`1<int32[]>::.ctor(class Program/Ref`1/Func`1<!0,!0>)  IL_0041:  stloc.1  IL_0042:  ldloc.0  IL_0043:  stloc.3  IL_0044:  br.s       IL_0046  IL_0046:  ldloc.3  IL_0047:  ret} // end of method Program::joik
解决方法 是的,匿名方法的MS实现有效地为每个级别的范围创建一个隐藏类,它需要从该范围捕获变量,并捕获所有相关的变量.我相信这是为了简单起见,但它确实可以不必要地增加一些对象的使用寿命.

每个匿名方法只能捕获其实际感兴趣的变量会更加优雅,但是这可能会使生活变得更加复杂…如果一个匿名方法捕获x和y,一个捕获的x和一个捕获的y,你’需要三个类:一个用于捕获x,一个用于捕获y,一个用于构成两个类(但不仅仅是两个变量).棘手的一点是,对于任何单个变量实例化,该变量需要生活在一个地方,所以指向它的所有内容都会看到相同的值,无论改变什么.

这不以任何方式违反规范,但可以认为是不幸的 – 我不知道它是否真的是在现实生活中被咬伤的人,但这当然是可能的.

好消息是,如果C#团队决定改进这一点,他们应该能够以完全向后兼容的方式执行此 *** 作,除非某些muppets依赖于不必要的延长生命周期.

总结

以上是内存溢出为你收集整理的c# – 离散匿名方法共享一个类?全部内容,希望文章能够帮你解决c# – 离散匿名方法共享一个类?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1261027.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存