Dynamicmethod والخروج المعلمات؟
-
18-09-2019 - |
سؤال
كيف يمكنني تحديد DynamicMethod للمندوب الذي لديه out
-Parameter، مثل هذا؟
public delegate void TestDelegate(out Action a);
دعنا نقول أنني أريد ببساطة طريقة تحدد a
حجة ل null
عندما اتصلت الطريقة.
لاحظ أنني أعلم أن طريقة أفضل للحكومة للتعامل مع هذا هو جعل الطريقة إرجاع Action
مندوب، ولكن هذا مجرد جزء مبسط من مشروع أكبر، ويتم إرجاع الطريقة المعنية بالفعل قيمة، أحتاج إلى التعامل مع out
المعلمة بالإضافة إلى ذلك، وبالتالي السؤال.
حاولت هذا:
using System;
using System.Text;
using System.Reflection.Emit;
namespace ConsoleApplication8
{
public class Program
{
public delegate void TestDelegate(out Action a);
static void Main(String[] args)
{
var method = new DynamicMethod("TestMethod", typeof(void),
new Type[] { typeof(Action).MakeByRefType() });
var il = method.GetILGenerator();
// a = null;
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Starg, 0);
// return
il.Emit(OpCodes.Ret);
var del = (TestDelegate)method.CreateDelegate(typeof(TestDelegate));
Action a;
del(out a);
}
}
}
ومع ذلك، أحصل على هذا:
VerificationException was unhandled:
Operation could destabilize the runtime.
على ال del(out a);
خط.
لاحظ أنه إذا قمت بعمل سطرين يقومان بتحميل NULL على المكدس ومحاولات تخزينه في الوسيطة، فإن الطريقة تعمل دون استثناءات.
يحرر: هل هذا هو النهج الأفضل؟
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Stind_Ref);
المحلول
أ out
حجة هي مجرد ref
حجة مع OutAttribute
تطبق على المعلمة.
لتخزينها إلى الحجة الفرعية، تحتاج إلى استخدام stind
OPCODE، لأن الحجة نفسها هي مؤشر مدار في الموقع الفعلي للكائن.
ldarg.0
ldnull
stind.ref