zoukankan      html  css  js  c++  java
  • c# 为实体赋值通过直接赋值,Emit,反射三种方法测试

     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     }

  • 相关阅读:
    语言混编总结二
    可执行文件与符号(表)
    iOS错误报告中关于崩溃地址的分析
    Find the build UUID in a Crash Report
    Symbolicating Crash Reports With atos
    iOS crash log 解析 symbol address = stack address
    Address space layout randomization
    ASLR(Address space layout randomization)地址空间布局随机化
    缓冲区溢出详解
    如何快速查看将C反汇编的代码
  • 原文地址:https://www.cnblogs.com/aaaaq/p/8643381.html
Copyright © 2011-2022 走看看