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)
我认为这是因为你将参数声明为object(System.Object)。
int是 System.ValueType:System.Object和A:System.Object。System.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)