Diskrete anonyme Methoden, die eine Klasse gemeinsam nutzen?
Ich habe ein bisschen mit Eric Lippert's @ gespieRef<T>
Klasse vonHie. In der IL habe ich festgestellt, dass anscheinend beide anonymen Methoden dieselbe generierte Klasse verwenden, obwohl dies bedeutet, dass die Klasse eine zusätzliche Variable hat.
Während die Verwendung nur einer neuen Klassendefinition vernünftig erscheint, finde ich es sehr merkwürdig, dass nur eine Instanz von<>c__DisplayClass2
geschaffen. Dies scheint zu implizieren, dass beide Instanzen vonRef<T>
referenzieren das gleiche<>c__DisplayClass2
Bedeutet das nicht, dassy
kann nicht gesammelt werden bisvart1
wird gesammelt, was viel später als nach @ passieren kajoik
kehrt zurück? Es gibt schließlich keine Garantie dafür, dass ein Idiot keine Funktion schreibt (direkt in IL), die direkt auf @ zugreify
durchvart1
aftrerjoik
kehrt zurück. Vielleicht könnte dies sogar mit Reflektion geschehen, anstatt über verrückte 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;
}
Running IL DASM hat bestätigt, dassvart1
undvart2
beide verwendeten<>__DisplayClass2
, das ein öffentliches Feld für x und für y enthielt. Die IL von 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