zoukankan      html  css  js  c++  java
  • c# 反射调用方法、获取设置值、好处和局限性

        /// 1 反射调用实例方法、静态方法、重载方法 选修:调用私有方法 调用泛型方法
        /// 2 反射字段和属性,分别获取值和设置值
        /// 3 反射的好处和局限
        class Program
        {
            /// 
            /// 反射的优点: 动态  
            /// 反射的缺点:
            ///     1 使用麻烦
            ///     2 避开编译器检查
            ///     3 性能问题!!!
            ///            100w次循环----- 普通方法 24ms
            ///                            反射     9206ms
            ///     缓存优化,把dll加载和类型获取  只执行一次
            ///            100w次循环----  普通方法 11ms
            ///                            反射     132ms
            ///                            反射影响更小了,
            ///     MVC-Asp.Net-ORM-IOC-AOP都在用反射,几乎都有缓存
            ///     MVC&&ORM  启动很慢,完成了很多初始化,反射的那些东西
            ///               后面运行就很快   
            static void Main(string[] args)
            {
                {
                    //知道方法名称,可以不做类型转换,直接调用方法
                    //反射创建了对象实例---有方法的名称--反射调用方法
                    //dll名称---类型名称---方法名称---我们就能调用方法
                    //MVC就是靠的这一招---调用Action
                    //http://localhost:9099/home/index  经过路由解析---会调用--HomeController--Index方法  
                    //浏览器输入时只告诉了服务器类型名称和方法名称,肯定是反射的
                    //MVC在启动时会先加载--扫描全部的dll--找到全部的Controller--存起来--请求来的时候,用Controller来匹配的---dll+类型名称
                    //1 MVC局限性的--Action重载--反射是无法区分---只能通过HttpMethod+特性httpget/httppost
                    //2 AOP--反射调用方法,可以在前后插入逻辑
                    Assembly assembly = Assembly.Load("DB.Mysql");
                    Type type = assembly.GetType("DB.Mysql.ReflectionTest");
                    object oTest = Activator.CreateInstance(type);
                    {
                        MethodInfo method = type.GetMethod("Show1");
                        method.Invoke(oTest, null);
                    }
                    {
                        MethodInfo method = type.GetMethod("Show2");
                        method.Invoke(oTest, new object[] { 123 });
                    }
                    #region 重载方法
                    {
                        MethodInfo method = type.GetMethod("Show3", new Type[] { });
                        method.Invoke(oTest, null);
                    }
                    {
                        MethodInfo method = type.GetMethod("Show3", new Type[] { typeof(int) });
                        method.Invoke(oTest, new object[] { 123 });
                    }
                    {
                        MethodInfo method = type.GetMethod("Show3", new Type[] { typeof(string) });
                        method.Invoke(oTest, new object[] { "一生为你" });
                    }
                    {
                        MethodInfo method = type.GetMethod("Show3", new Type[] { typeof(int), typeof(string) });
                        method.Invoke(oTest, new object[] { 234, "心欲无痕" });
                    }
                    {
                        MethodInfo method = type.GetMethod("Show3", new Type[] { typeof(string), typeof(int) });
                        method.Invoke(oTest, new object[] { "PHS", 345 });
                    }
                    #endregion
                    #region 调用静态方法
                    {
                        MethodInfo method = type.GetMethod("Show5");
                        method.Invoke(oTest, new object[] { "张中魁" });//静态方法实例可以要
                    }
                    {
                        MethodInfo method = type.GetMethod("Show5");
                        method.Invoke(null, new object[] { "张中魁" });//静态方法实例也可以不要
                    }
                    #endregion
                    #region 调用私有方法
                    {
                        var method = type.GetMethod("Show4", BindingFlags.Instance | BindingFlags.NonPublic);
                        method.Invoke(oTest, new object[] { "我是老王" });
                    }
                    #endregion
                }
                #region 泛型方法
                {
                    Assembly assembly = Assembly.Load("DB.Mysql");
                    Type type = assembly.GetType("DB.Mysql.GenericDouble`1").MakeGenericType(typeof(int));
                    object oObject = Activator.CreateInstance(type);
                    MethodInfo method = type.GetMethod("Show").MakeGenericMethod(typeof(string), typeof(DateTime));
                    method.Invoke(oObject, new object[] { 345, "我爱祖国", DateTime.Now });
                }
                #endregion
                #region 反射字段和属性,分别获取值和设置值
                {
                    Assembly assembly = Assembly.Load("DB.Mysql");
                    Type type = assembly.GetType("DB.Mysql.ReflectionTest");
                    object oTest = Activator.CreateInstance(type);
                    foreach (var prop in type.GetProperties())
                    {
                        if (prop.Name.Equals("Id"))
                        {
                            prop.SetValue(oTest, 123);
                        }
                        else if (prop.Name.Equals("Name"))
                        {
                            prop.SetValue(oTest, "老王");
                        }
                        Console.WriteLine($"{type.Name}.{prop.Name}={prop.GetValue(oTest)}");
                    }
    
    
                    foreach (var field in type.GetFields())
                    {
                        if (field.Name.Equals("Description"))
                        {
                            field.SetValue(oTest, "是个好邻居");
                        }
                        Console.WriteLine($"{type.Name}.{field.Name}={field.GetValue(oTest)}");
                    }
                }
                #endregion
              
                Console.ReadKey();
            }
        }
     #region 反射性能测试 普通方法 24ms   反射     9206ms
                {
                    long commonTime = 0;
                    long reflectionTime = 0;
                    {
                        Stopwatch watch = new Stopwatch();
                        watch.Start();
                        for (int i = 0; i < 1_000_000; i++)
                        {
                            IDBHelper iDBHelper = new MySqlHelper();
                            iDBHelper.Query();
                        }
                        watch.Stop();
                        commonTime = watch.ElapsedMilliseconds;
                    }
                    {
                        Stopwatch watch = new Stopwatch();
                        watch.Start();
                        for (int i = 0; i < 1_000_000; i++)
                        {
                            Assembly assembly = Assembly.Load("DB.Mysql");//1 动态加载
                            Type dbHelperType = assembly.GetType("DB.Mysql.MySqlHelper");//2 获取类型
                            object oDBHelper = Activator.CreateInstance(dbHelperType);//3 创建对象
                            IDBHelper dbHelper = (IDBHelper)oDBHelper;//4 接口强制转换
                            dbHelper.Query();//5 方法调用
                        }
                        watch.Stop();
                        reflectionTime = watch.ElapsedMilliseconds;
                    }
    
                    Console.WriteLine("commonTime={0} reflectionTime={1}", commonTime, reflectionTime);
                }
                #endregion

    测试结果:

     #region 缓存优化,把dll加载和类型获取  只执行一次 普通方法11ms 反射132ms
                {
                    long commonTime = 0;
                    long reflectionTime = 0;
                    {
                        Stopwatch watch = new Stopwatch();
                        watch.Start();
                        for (int i = 0; i < 1_000_000; i++)
                        {
                            IDBHelper iDBHelper = new MySqlHelper();
                            iDBHelper.Query();
                        }
                        watch.Stop();
                        commonTime = watch.ElapsedMilliseconds;
                    }
                    {
                        Stopwatch watch = new Stopwatch();
                        watch.Start();
                        Assembly assembly = Assembly.Load("DB.Mysql");//1 动态加载
                        Type dbHelperType = assembly.GetType("DB.Mysql.MySqlHelper");//2 获取类型
                        for (int i = 0; i < 1_000_000; i++)
                        {
                            object oDBHelper = Activator.CreateInstance(dbHelperType);//3 创建对象
                            IDBHelper dbHelper = (IDBHelper)oDBHelper;//4 接口强制转换
                            dbHelper.Query();//5 方法调用
                        }
                        watch.Stop();
                        reflectionTime = watch.ElapsedMilliseconds;
                    }
    
                    Console.WriteLine("commonTime={0} reflectionTime={1}", commonTime, reflectionTime);
                }
                #endregion

    测试结果:

    namespace DB.Interface
    {
        public interface IDBHelper
        {
            void Query();
        }
    }
    namespace DB.Mysql
    {
        public class MySqlHelper : IDBHelper
        {
            public string name { get; set; }
            public MySqlHelper()
            {
            }
         
    
            public void Query()
            {
            }
        }
    }
    namespace DB.Mysql
    {
        /// <summary>
        /// 反射测试类
        /// </summary>
        public class ReflectionTest
        {
            public int Id { get; set; }
            public string Name { get; set; }
    
            public string Description;
    
            #region Identity
            /// <summary>
            /// 无参构造函数
            /// </summary>
            public ReflectionTest()
            {
                Console.WriteLine("这里是{0}无参数构造函数", this.GetType());
            }
    
            /// <summary>
            /// 带参数构造函数
            /// </summary>
            /// <param name="name"></param>
            public ReflectionTest(string name)
            {
                Console.WriteLine("这里是{0} 有参数构造函数", this.GetType());
            }
    
            public ReflectionTest(int id)
            {
                Console.WriteLine("这里是{0} 有参数构造函数", this.GetType());
            }
            #endregion
    
            #region Method
            /// <summary>
            /// 无参方法
            /// </summary>
            public void Show1()
            {
                Console.WriteLine("这里是{0}的Show1", this.GetType());
            }
            /// <summary>
            /// 有参数方法
            /// </summary>
            /// <param name="id"></param>
            public void Show2(int id)
            {
    
                Console.WriteLine("这里是{0}的Show2", this.GetType());
            }
            /// <summary>
            /// 重载方法之一
            /// </summary>
            /// <param name="id"></param>
            /// <param name="name"></param>
            public void Show3(int id, string name)
            {
                Console.WriteLine("这里是{0}的Show3", this.GetType());
            }
            /// <summary>
            /// 重载方法之二
            /// </summary>
            /// <param name="name"></param>
            /// <param name="id"></param>
            public void Show3(string name, int id)
            {
                Console.WriteLine("这里是{0}的Show3_2", this.GetType());
            }
            /// <summary>
            /// 重载方法之三
            /// </summary>
            /// <param name="id"></param>
            public void Show3(int id)
            {
    
                Console.WriteLine("这里是{0}的Show3_3", this.GetType());
            }
            /// <summary>
            /// 重载方法之四
            /// </summary>
            /// <param name="name"></param>
            public void Show3(string name)
            {
    
                Console.WriteLine("这里是{0}的Show3_4", this.GetType());
            }
            /// <summary>
            /// 重载方法之五
            /// </summary>
            public void Show3()
            {
    
                Console.WriteLine("这里是{0}的Show3_1", this.GetType());
            }
            /// <summary>
            /// 私有方法
            /// </summary>
            /// <param name="name"></param>
            private void Show4(string name)
            {
                Console.WriteLine("这里是{0}的Show4", this.GetType());
            }
            /// <summary>
            /// 静态方法
            /// </summary>
            /// <param name="name"></param>
            public static void Show5(string name)
            {
                Console.WriteLine("这里是{0}的Show5", typeof(ReflectionTest));
            }
       
    
            #endregion
        }
    
    
        /// <summary>
        /// 泛型方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public class GenericDouble<T>
        {
            public void Show<W, X>(T t, W w, X x)
            {
                Console.WriteLine("t.type={0},w.type={1},x.type={2}", t.GetType().Name, w.GetType().Name, x.GetType().Name);
            }
        }
    }
  • 相关阅读:
    atitit.解决struts2 SpringObjectFactory.getClassInstance NullPointerException
    atitit。 hb Hibernate sql 查询使用
    atitit.插件体系设计总结o73.doc
    Atitit.可视化编程jbpm6 的环境and 使用总结...
    paip.自动import的实现跟java.lang.SecurityException Prohibited package name java
    Linux下tar.xz结尾的文件的解压方法
    ubuntu下的Samba配置:使每个用户可以用自己的用户名和密码登录自己的home目录
    ubuntu Linux离线安装软件包
    C语言文件操作解析(一)[转载]
    PDF XChange Viewer文件关联
  • 原文地址:https://www.cnblogs.com/wangdash/p/11888845.html
Copyright © 2011-2022 走看看