数値でのフィールド参照
• C#で擬似的に書くと
static int GetVolume(Point p)
{
return p.X * p.Y * p.Z;
}
var pp = (byte*)&p;
var x = *((int*)pp);
var y = *((int*)(pp + 4));
var z = *((int*)(pp + 8));
return x * y * z;
4とか8とかの数値に
※これ、一応C#として有効なコード(unsafe)
ILを直接生成
• ILGenerator
var t = typeof(Point);
var x = t.GetField("X");
var y = t.GetField("Y");
var z = t.GetField("Z");
var m = new DynamicMethod("GetVolume", typeof(int), new[] { t });
m.DefineParameter(1, ParameterAttributes.In, "p");
var gen = m.GetILGenerator();
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldfld, x);
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldfld, y);
gen.Emit(OpCodes.Mul);
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldfld, z);
gen.Emit(OpCodes.Mul);
gen.Emit(OpCodes.Ret);
ILを直接生成
• ILGenerator
ポイントの行:
var gen = m.GetILGenerator();
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldfld, x);
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldfld, y);
gen.Emit(OpCodes.Mul);
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldfld, z);
gen.Emit(OpCodes.Mul);
gen.Emit(OpCodes.Ret);