zoukankan      html  css  js  c++  java
  • 源码发布 DynamicMethodProxyFactory组件

    在前面的文章改进的“以非泛型方式调用泛型方法”之基于DynamicMethod的实现中,提到了一种通过DynamicMethod以非泛型方法代理访问泛型方法的较佳方法(无额外代码定义需要,执行时间大约相当于直接调用泛型方法的3-4倍)。本文介绍的组件在前文思路的基础上,进行进一步的扩展,封装成一个较通用的DynamicMethodProxyFactory组件。除了可以较高性能访问任意的静态或非静态、泛型或非泛行方法之外,利用DynamicMethod可将代码插入内存中已载入的Module的能力,提供了在程序集外实例化指定Module中的internal类型,在程序集外调用internal类型的方法和public类型的internal方法的支持。

    该组件实现如下功能:
    1、以通用的非泛行方法Delegate访问任意方法(泛型或非泛型,静态或非静态);
    2、支持在程序集外调用指定Module中的internal类型的任意属性(属性本质上可以通过它的get/set方法以方法的形式访问)和方法和public类型的internal方法;
    3、支持创建并返回指定Module中的internal类型的实例;

    以非泛型方式调用泛型方法的意义在前文中已经讨论过了,对很多支持泛型方法的框架来说,是非常必要的代替反射的功能(相比反射性能提升3-4个数量级)。

    那么访问internal类型和方法有什么意义呢?除了突破原来的CLR的不能跨程序集访问internal成员的限制这个明显的好处之外,更大的意义在于我们可以使用.Net Framework提供的很多非常有用的internal组件,这些组件,MS出于各种原因标记为了internal,但是,既然提供了,我们就有理由去使用它,对于实现我们自己的组件时充分利用.Net Framework内置的这些组件而减少我们重复劳动的工作量也很有意义。


    使用演示:

     1using System;
     2using System.Collections.Generic;
     3using System.Reflection;
     4using System.Reflection.Emit;
     5using System.Text;
     6
     7namespace DynamicMethodProxyTest
     8{
     9    public class Program
    10    {
    11        //用于测试的静态方法
    12        public static void Add<T>(T obj, IList<T> list)
    13        {
    14            //list.Add同时也是用于测试的非静态方法
    15            list.Add(obj);
    16        }

    17
    18        private const int REPEAT_TIME = 20000000;
    19
    20        static void Main(string[] args)
    21        {
    22            //创建一个内置缓存支持的DynamicMethodProxyFactory实例
    23            NBear.DynamicMethodHelper.DynamicMethodProxyFactory fac = new NBear.DynamicMethodHelper.CachableDynamicMethodProxyFactory();
    24
    25            //创建一个internal的System.Web.HttpDictionary类实例
    26            Console.WriteLine("Create an instance of internal type - System.Web.HttpDictionary.");
    27            object temp = fac.CreateInstance(typeof(System.Web.HttpApplication).Module, "System.Web.HttpDictionary"falsefalse);
    28
    29            //创建访问该实例的SetValue和GetValue方法的DynamicMethosProxyDelegate
    30            Console.WriteLine("Create DynamicMethodProxyDelegate of HttpDictionary's SetValue and GetValue methods.");
    31            NBear.DynamicMethodHelper.DynamicMethodProxyDelegate setDelegate = fac.GetMethodDelegate(typeof(System.Web.HttpApplication).Module, temp.GetType().GetMethod("SetValue", BindingFlags.NonPublic | BindingFlags.Instance));
    32            NBear.DynamicMethodHelper.DynamicMethodProxyDelegate getDelegate = fac.GetMethodDelegate(typeof(System.Web.HttpApplication).Module, fac.GetMethodInfoBySignature(temp.GetType(), "System.Object GetValue(System.String)"falsefalse));
    33
    34            //在该实例上 Set & Get 测试数据
    35            Console.WriteLine("set \"test value\" on the internal type instance");
    36            setDelegate(temp, "test""test value");
    37            Console.WriteLine("get the test value from the internal type instance: " + getDelegate(temp, "test"));
    38
    39            //测试DynamicMethodProxyDelegate的性能
    40            Console.WriteLine("Test the performance of DynamicMethodProxyDelegate.");
    41            List<int> list = new List<int>();
    42            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
    43            watch.Reset();
    44            watch.Start();
    45            for (int i = 0; i < REPEAT_TIME; i++)
    46            {
    47                //这里是直接泛型调用
    48                Program.Add<int>(i, list);
    49            }

    50            watch.Stop();
    51            long l1 = watch.ElapsedMilliseconds;
    52            watch.Reset();
    53            MethodInfo mi = typeof(Program).GetMethod("Add");
    54            //创建一个静态方法的StaticDynamicMethodDelegate
    55            NBear.DynamicMethodHelper.StaticDynamicMethodProxyDelegate sdmd = fac.GetStaticMethodDelegate(mi, typeof(int));
    56            watch.Start();
    57            for (int i = 0; i < REPEAT_TIME; i++)
    58            {
    59                //通过StaticDynamicMethodDelegate以非泛型方式访问泛型方法
    60                sdmd(i, list);
    61            }

    62            watch.Stop();
    63            long l2 = watch.ElapsedMilliseconds;
    64            watch.Reset();
    65            MethodInfo mi2 = list.GetType().GetMethod("Add");
    66            //创建一个DynamicMethodDelegate访问同样的Add方法
    67            NBear.DynamicMethodHelper.DynamicMethodProxyDelegate dmd = fac.GetMethodDelegate(mi2);
    68            watch.Start();
    69            for (int i = 0; i < REPEAT_TIME; i++)
    70            {
    71                //通过DynamicMethodDelegate访问
    72                dmd(list, i);
    73            }

    74            watch.Stop();
    75            long l3 = watch.ElapsedMilliseconds;
    76            Console.WriteLine("{0}\nDirectly vs Static vs Non-static\n{1} vs {2} vs {3}", list.Count, l1, l2, l3);
    77            Console.ReadLine();
    78        }

    79    }

    80}


    下载测试代码和类库源码

  • 相关阅读:
    尚硅谷Docker笔记(6) DockerFile解析
    注意防踩坑系列
    尚硅谷Docker笔记(1) Docker简介
    尚硅谷Docker笔记(4) Docker 镜像
    尚硅谷Docker笔记(8) 本地镜像发布到阿里云
    尚硅谷Docker笔记(2) Docker安装
    SQL中join连接查询时条件放在on后与where后的区别
    尚硅谷Docker笔记(3) Docker常用命令
    尚硅谷Docker笔记(7) Docker常用软件安装
    关于存储过程的几个sql
  • 原文地址:https://www.cnblogs.com/teddyma/p/690946.html
Copyright © 2011-2022 走看看