1 public class Class1
2 {
3 public static void Button_Click()
4 {
5 TestDemoEntity entity;
6 Stopwatch watch;
7 int length = 1000000;
8
9 #region 直接赋值 1
10 watch = new Stopwatch();
11 watch.Start();
12 entity = new TestDemoEntity();
13 for (int i = 0; i < length; i++)
14 {
15 entity.Name = "测试";
16 }
17 watch.Start();
18 Console.WriteLine("直接赋值:" + watch.ElapsedMilliseconds);
19 #endregion
20
21 #region 通过Emit赋值 2
22 watch = new Stopwatch();
23 watch.Start();
24 entity = new TestDemoEntity();
25 var emitSetter = EmitSetter<TestDemoEntity>("Name");
26 for (int i = 0; i < length; i++)
27 {
28 emitSetter(entity, "测试" + i);
29 }
30 watch.Start();
31 Console.WriteLine("通过Emit赋值:" + watch.ElapsedMilliseconds);
32
33 #endregion
34
35 #region 通过反射赋值 3
36 watch = new Stopwatch();
37 watch.Start();
38 entity = new TestDemoEntity();
39 for (int i = 0; i < length; i++)
40 {
41 ReflectSetter(entity, "Name", "测试");
42 }
43 watch.Start();
44 Console.WriteLine("通过反射赋值:" + watch.ElapsedMilliseconds);
45
46 #endregion
47 }
48
49 public static Action<T, object> EmitSetter<T>(string propertyName)
50 {
51 var type = typeof(T);
52 var dynamicMethod = new DynamicMethod("EmitCallable", null, new[] { type, typeof(object) }, type.Module);//定义和表示一个可以编译,执行和丢弃的动态方法
53 var iLGenerator = dynamicMethod.GetILGenerator();//返回方法的Microsoft中间语言(MSIL)生成器,默认的MSIL流大小为64字节
54 if (iLGenerator != null)
55 {
56 var callMethod = type.GetMethod("set_" + propertyName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public);//获取字段set属性
57 if (callMethod != null)
58 {
59 var parameterInfo = callMethod.GetParameters()[0];
60 if (parameterInfo != null)
61 {
62 var local = iLGenerator.DeclareLocal(parameterInfo.ParameterType, true);
63 #region Emit()将指定的指令放在指令流上,该方法接收一个IL流。EmitCall()将 call 或 callvirt 指令置于 Microsoft 中间语言 (MSIL) 流,以调用varargs 方法。我们看到OpCodes类,该类描述中间语言 (IL) 指令
64 iLGenerator.Emit(OpCodes.Ldarg_1);
65 if (parameterInfo.ParameterType.IsValueType)
66 {
67 // 如果是值类型,拆箱
68 iLGenerator.Emit(OpCodes.Unbox_Any, parameterInfo.ParameterType);
69 }
70 else
71 {
72 // 如果是引用类型,转换
73 iLGenerator.Emit(OpCodes.Castclass, parameterInfo.ParameterType);
74 }
75 iLGenerator.Emit(OpCodes.Stloc, local);//OpCodes类,该类描述中间语言 (IL) 指令
76 iLGenerator.Emit(OpCodes.Ldarg_0);//将指定的指令放在指令流上,该方法接收一个IL流
77 iLGenerator.Emit(OpCodes.Ldloc, local);
78 iLGenerator.EmitCall(OpCodes.Callvirt, callMethod, null);//将 call 或 callvirt 指令置于 Microsoft 中间语言 (MSIL) 流,以调用varargs 方法
79 iLGenerator.Emit(OpCodes.Ret);
80 #endregion
81 }
82 }
83 }
84 return dynamicMethod.CreateDelegate(typeof(Action<T, object>)) as Action<T, object>;//CreateDelegate()完成动态方法并创建一个可用于执行它的委托。
85 }
86 public static void ReflectSetter(object obj, string propertyName, object propertyValue)
87 {
88 var type = obj.GetType();
89 var propertyInfo = type.GetProperty(propertyName);
90 propertyInfo.SetValue(obj, propertyValue, null);
91 }
92 }
93 public class TestDemoEntity
94 {
95 public string Name { get; set; }
96 }