次のプログラム例は、オペコードldvirtftn
の使用方法を把握しようとしています。名前には、仮想関数ポインタをスタックにロードするときに使用するオペコードであることが示されています。例のコードでは、私は2つの静的メソッドLdftn
とLdvirtftn
の型を作成していますが、これらのメソッドは両方ともBase.Method()
のオープンデリゲートを返します。Ldftn
はldftn
オペコードを使用し、Base.Method
は仮想です。 2番目の方法はLdvirtftn
を使用し、無効なプログラムを作成したようです。私は間違って何をしていますか?混乱以外のこのオペコードの目的は何ですか?ここでLdvirtftnオペコードはいつ、どのように使用しますか?
public class Base
{
public virtual void Method()
{
Console.WriteLine("Base");
}
}
public class Child : Base
{
public override void Method()
{
Console.WriteLine("Child");
}
}
class Program
{
static void Main(string[] args)
{
AssemblyBuilder ab =AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("Test"),AssemblyBuilderAccess.RunAndSave);
ModuleBuilder mb = ab.DefineDynamicModule("TestModule");
TypeBuilder tb = mb.DefineType("TestType");
MethodBuilder method = tb.DefineMethod("Ldftn",MethodAttributes.Public | MethodAttributes.Static, typeof(Action<Base>), Type.EmptyTypes);
var ilgen = method.GetILGenerator();
ilgen.Emit(OpCodes.Ldnull);
ilgen.Emit(OpCodes.Ldftn, typeof(Base).GetMethod("Method"));
ilgen.Emit(OpCodes.Newobj, typeof(Action<Base>).GetConstructors()[0]);
ilgen.Emit(OpCodes.Ret);
method = tb.DefineMethod("Ldvirtftn", MethodAttributes.Public | MethodAttributes.Static, typeof(Action<Base>), Type.EmptyTypes);
ilgen = method.GetILGenerator();
ilgen.Emit(OpCodes.Ldnull);
ilgen.Emit(OpCodes.Ldvirtftn, typeof(Base).GetMethod("Method"));
ilgen.Emit(OpCodes.Newobj, typeof(Action<Base>).GetConstructors()[0]);
ilgen.Emit(OpCodes.Ret);
var type = tb.CreateType();
var func = Delegate.CreateDelegate(typeof(Func<Action<Base>>),tb.GetMethod("Ldftn")) as Func<Action<Base>>;
var func2 = Delegate.CreateDelegate(typeof(Func<Action<Base>>), tb.GetMethod("Ldvirtftn")) as Func<Action<Base>>;
func()(new Child());
func2()(new Child());
}
}
実際、仮想ディスパッチは、私が後にしたものでした。私はvirtftnがインスタンスを渡している間だけ動作していることを知らなかったので、行くために送ると思います:ld instance、dup、ldvirtftnメソッド、newobj delegate ctor? –
"static" 'Func'デリゲートと ''インスタンス "' Func 'デリゲートの両方を作成するのに、静的な' string - > int'関数を使うことができます。いずれかのデリゲート型の 'ldnull'(または' ldstr')+ 'ldftn' +' newobj'です。 –