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);
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/wangdash/p/11888845.html