سؤال

كيف يمكنني تحديد 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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top