私はC#コンパイラのいくつかの奇妙な動作に遭遇したようです。実行メソッドの開始時にC#クロージャのヒープ割り当てが起こっています
static void Main(string[] args)
{
Foo(false, 8);
}
public static void Foo(bool execute, int x)
{
if (execute)
{
Task.Run(() => Console.WriteLine(x));
}
}
この(リリースで)起こっていくつかの予想外の割り当てを示しています
は、次のサンプル・コードを考えてみましょう。
.method public hidebysig static void
Foo(
bool execute,
int32 x
) cil managed
{
.maxstack 2
.locals init (
[0] class Test.Program/'<>c__DisplayClass1_0' 'CS$<>8__locals0'
)
IL_0000: newobj instance void Test.Program/'<>c__DisplayClass1_0'::.ctor()
IL_0005: stloc.0 // 'CS$<>8__locals0'
IL_0006: ldloc.0 // 'CS$<>8__locals0'
IL_0007: ldarg.1 // x
IL_0008: stfld int32 Test.Program/'<>c__DisplayClass1_0'::x
// [18 13 - 18 25]
IL_000d: ldarg.0 // execute
IL_000e: brfalse.s IL_0022
// [20 17 - 20 54]
IL_0010: ldloc.0 // 'CS$<>8__locals0'
IL_0011: ldftn instance void Test.Program/'<>c__DisplayClass1_0'::'<Foo>b__0'()
IL_0017: newobj instance void [mscorlib]System.Action::.ctor(object, native int)
IL_001c: call class [mscorlib]System.Threading.Tasks.Task [mscorlib]System.Threading.Tasks.Task::Run(class [mscorlib]System.Action)
IL_0021: pop
// [22 9 - 22 10]
IL_0022: ret
} // end of method Program::Foo
私はここで何かが足りない、誰もがこの奇妙な振る舞いについての説明がありますん:ILを調べると閉鎖によってトリガヒープの割り当てではなく条件の内側よりも、機能の非常に開始時に表示されていることをすることを示しています? Roslynが実際にそれらを実行するかどうかにかかわらずクロージャを割り当てるコードを生成することは可能でしょうか?
"予想外の割り当てが発生しています" - 期待が間違っていた可能性もあります。 –