c# - Discrete Anonymous methods sharing a class? -


i playing bit eric lippert's ref<t> class here. noticed in il looked both anonymous methods using same generated class, though meant class had variable.

while using 1 new class definition seems reasonable, strikes me odd 1 instance of <>c__displayclass2 created. seems imply both instances of ref<t> referencing same <>c__displayclass2 doesn't mean y cannot collected until vart1 collected, may happen later after joik returns? after all, there no guarantee idiot won't write function (directly in il) directly accesses y through vart1 aftrer joik returns. maybe done reflection instead of via crazy 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 { { 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; } 

running il dasm confirmed vart1 , vart2 both used <>__displayclass2, contained public field x , y. il of joik:

.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> cs$1$0000)   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 

yes, ms implementation of anonymous methods creates 1 hidden class per level of scope needs capture variables from, , captures all relevant variables scope. believe done sake of simplicity, can indeed increase lifetime of objects unnecessarily.

it more elegant each anonymous method only capture variables interested in. however, make life considerably more complicated... if 1 anonymous method captured x , y, 1 captured x , 1 captured y, you'd need 3 classes: 1 capturing x, 1 capturing y, , 1 composing 2 (but not having 2 variables). tricky bit single variable instantiation, variable needs live in 1 place refers sees same value, whatever changes it.

this doesn't violate spec in way, considered unfortunate - don't know whether it's bitten people in real life, it's possible.

the news if c# team decide improve this, should able in entirely backwardly compatible way, unless muppets relying on lifetimes being extended unnecessarily.


Comments

Popular posts from this blog

ASP.NET/SQL find the element ID and update database -

c++ - Compiling static TagLib 1.6.3 libraries for Windows -

PostgreSQL 9.x - pg_read_binary_file & inserting files into bytea -