DynamicMethod和类型检查

Ale*_*x A 9 .net c# dynamicmethod

有人可以解释或指出解释为什么运行时类型检查不会出现在下面的示例中 - 字符串属性可以设置为任何类型值...
在非常意外的地方坚持这个并且真的很惊讶

using System;
using System.Reflection;
using System.Reflection.Emit;

namespace Dynamics
{
internal class Program
    {
    private static void Main(string[] args)
    {
        var a = new A();
        a.Name = "Name";
        Console.WriteLine(a.Name.GetType().Name);

        PropertyInfo pi = a.GetType().GetProperty("Name");          

        DynamicMethod method = new DynamicMethod(
                "DynamicSetValue", // NAME
                null, // return type
                new Type[] 
                            {
                                typeof(object), // 0, objSource
                                typeof(object), // 1, value
                            }, // parameter types
                typeof(Program), // owner
                true); // skip visibility

        ILGenerator gen = method.GetILGenerator();
        gen.Emit(OpCodes.Ldarg_0);
        gen.Emit(OpCodes.Ldarg_1);
        gen.Emit(OpCodes.Call, pi.GetSetMethod(true));
        gen.Emit(OpCodes.Ret);

        SetValue setMethod = (SetValue)method.CreateDelegate(typeof(SetValue));

        int val = 123;
        setMethod(a, val);
        Console.WriteLine(a.Name.GetType().Name);

        A anotherA = new A();
        anotherA.Name = "Another A";
        setMethod(a, anotherA);
        Console.WriteLine(a.Name.GetType().Name);
    }
}

public class A
{
    public string Name { get; set; }
}

public delegate void SetValue(object obj, object val);
}
Run Code Online (Sandbox Code Playgroud)

Fra*_*k59 0

我认为这是因为你将参数声明为objectSystem.Object)。 intSystem.ValueType:System.ObjectA:System.ObjectSystem.Object是所有类的基类(http://msdn.microsoft.com/en-us/library/system.object.aspx)。例如,如果您将其更改typeof(object)为,您将收到强制转换错误。typeof(string)

编辑:我认为您的示例中禁用了参数类型检查,因为您替换了属性 getter/setter 的调用。如果您需要对调用动态方法进行类型检查,您可以尝试使用以下代码:

    var a = new A();
    a.Name = "Name";
    Console.WriteLine(a.Name.GetType().Name);

    PropertyInfo pi = a.GetType().GetProperty("Name");          

    DynamicMethod method = new DynamicMethod(
            "DynamicSetValue", // NAME
            null, // return type
            new Type[] 
                        {
                            typeof(Object), // 0, objSource
                            pi.PropertyType, // 1, value
                        }, // parameter types
            typeof(OracleUserOlapRepositoryTests), // owner
            true); // skip visibility

    ILGenerator gen = method.GetILGenerator();
    gen.Emit(OpCodes.Ldarg_0);
    gen.Emit(OpCodes.Ldarg_1);
    gen.Emit(OpCodes.Call, pi.GetSetMethod(true));
    gen.Emit(OpCodes.Ret);

   //correct  
   method.Invoke(a, new object[]{a,"test"});

   //error  
   method.Invoke(a, new object[]{a,new List<String>()});

   Console.WriteLine(a.Name.GetType().Name);
Run Code Online (Sandbox Code Playgroud)