如何在DynamicMethod中调用Nullable.HasValue?

时间:2013-09-13 15:42:36

标签: .net cil il dynamicmethod dynamic-method

我正在使用DynamicMethod编写一些代码。在我的DynamicMethod中,我想调用Nullable.HasValue(以及Nullable.Value)属性。我写了一些代码来做一些,但我一直得到Operation could destabilize the runtime error

这是我的代码:

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(testHasValue()(true));
        }

        delegate bool HasValueDelegate(bool? a);
        static HasValueDelegate testHasValue()
        {
            MethodInfo GetNullableHasValue = typeof(bool?).GetProperty("HasValue").GetGetMethod();

            DynamicMethod method = new DynamicMethod("Wow", typeof(bool), new Type[] { typeof(bool?) });
            ILGenerator generator = method.GetILGenerator();

            MethodInfo GetNullableValue = typeof(bool?).GetProperty("Value").GetGetMethod();            

            generator.Emit(OpCodes.Ldarg_0);
            // Callvirt results in the same error.
            generator.Emit(OpCodes.Call, GetNullableHasValue); 
            generator.Emit(OpCodes.Ret);

            return ((HasValueDelegate)(method.CreateDelegate(typeof(HasValueDelegate)))).Invoke;
        }
    }
}

我应该补充说,根据Telerik JustDecompile,返回HasValue属性的C#代码转换为IL如下:

    static bool hasValue(bool? a)
    {
        return a.HasValue;
    }

.method private hidebysig static bool hasValue (
        valuetype [mscorlib]System.Nullable`1<bool> a
    ) cil managed 
{
    IL_0000: ldarga.s a
    IL_0002: call instance bool valuetype [mscorlib]System.Nullable`1<bool>::get_HasValue()
    IL_0007: ret
}

1 个答案:

答案 0 :(得分:3)

我想出来了。

generator.Emit(OpCodes.Ldarg_0);

应该是

generator.Emit(OpCodes.Ldarga_S, 0);