zoukankan      html  css  js  c++  java
  • C# 反射Reflection——反射反射程序员的快乐

    一、什么是反射
    反射Reflection:System.Reflection,是.Net Framework提供的一个帮助类库,可以读取并使用metadata。
    反射是无处不在的,MVC-Asp.Net-ORM-IOC-AOP 几乎所有的框架都离不开反射
    如下图是程序执行的过程,高级语言经过编译器编译得到dll/exe文件,这里的文件可以跨平台使用,编译后的文件中其实包括了metadata元数据(数据清单,描述了DLL/exe里面的各种信息)和IL(也是一种面向对象语言,但是不太好阅读)在经过CLR/JIT编译得到可以被计算机所执行的机器码。
    二、反射的使用
    一)反射动态加载程序集
                Assembly assembly1 = Assembly.LoadFrom(@"DB.MySql.dll");//当前路径
                Assembly assembly2 = Assembly.LoadFile(@"D:
    uanmouMyReflectioninDebugDB.MySql.dll");//dll、exe文件完整路径
                Assembly assembly3 = Assembly.Load(@"DB.MySql");//dll、exe名称   dll/exe需要拷贝至程序bin文件夹下
    View Code

    二)简单工厂生产对应实体

            /// <summary>
            /// 简单工厂生产对应实体
            /// </summary>
            /// <returns></returns>
            public static T CreateInstance<T>()
            {
                Assembly assembly = Assembly.Load(ConfigurationManager.AppSettings["DalDllName"]);//加载dll
                Type dalType = assembly.GetType(ConfigurationManager.AppSettings["DalTypeName"]);//获取类型
                return (T)Activator.CreateInstance(dalType);//创建对象
                //var newType = dalType.MakeGenericType(typeof(T));//获取泛型类型
                //return (T)Activator.CreateInstance(newType);创建泛型类型对象
            }
    View Code

    三)常用方法

                Type[] types= assembly.GetTypes();//获取程序集所有类型
                Type type= assembly.GetType("TypeName");//获取指定类型
                MethodInfo[] methods= type.GetMethods();//获取所有方法
                MethodInfo method= type.GetMethod("methodName");//获取指定方法
                PropertyInfo[] propertys= type.GetProperties();//获取所有属性
                PropertyInfo property = type.GetProperty("propertyName");//获取指定属性
                FieldInfo[] fields= type.GetFields();//获取所有字段
                FieldInfo field = type.GetField("fieldName");//获取指定字段
                Attribute attribute = type.GetCustomAttribute(typeof(DisplayNameAttribute));//获取指定特性
    View Code

    反射调用多参数构造函数,方法

        /// <summary>
        /// 反射测试类
        /// </summary>
        public class ReflectionTest
        {
            #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
        }
    View Code
                    Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");
                    Type type = assembly.GetType("Ruanmou.DB.SqlServer.ReflectionTest");
                    object oTest = Activator.CreateInstance(type);//反射调用无参数构造函数
                    object oTest2 = Activator.CreateInstance(type, new object[] { 123 });//反射调用一个int类型参数构造函数
                    foreach (var method in type.GetMethods())
                    {
                        Console.WriteLine(method.Name);
                        foreach (var parameter in method.GetParameters())//获取方法参数
                        {
                            Console.WriteLine($"{parameter.Name}  {parameter.ParameterType}");
                        }
                    }
                    {
                        ReflectionTest reflection = new ReflectionTest();
                        reflection.Show1();
                    }
                    {
                        MethodInfo method = type.GetMethod("Show1");
                        //if()
                        method.Invoke(oTest, null);//oTest调用无参数方法
                    }
                    {
                        MethodInfo method = type.GetMethod("Show2");
                        method.Invoke(oTest, new object[] { 123 });//oTest调用一个int类型参数方法
                    }
                    {
                        MethodInfo method = type.GetMethod("Show3", new Type[] { });
                        method.Invoke(oTest, null);//oTest调用无参数重载方法
                    }
                    {
                        MethodInfo method = type.GetMethod("Show3", new Type[] { typeof(int) });
                        method.Invoke(oTest, new object[] { 123 });//oTest调用一个int类型参数重载方法
                    }
                    
                    {
                        MethodInfo method = type.GetMethod("Show5");
                        method.Invoke(oTest, new object[] { "String" });//静态方法实例可以要
                    }
                    {
                        MethodInfo method = type.GetMethod("Show5");
                        method.Invoke(null, new object[] { "string" });//静态方法实例也可以不要
                    }
    View Code
                        var method = type.GetMethod("Show4", BindingFlags.Instance | BindingFlags.NonPublic);
                        method.Invoke(oTest, new object[] { "私有方法" });
    反射调用私有方法

    反射调用泛型方法、泛型类

        public class GenericClass<T, W, X>
        {
            public void Show(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);
            }
        }
    
        public class GenericMethod
        {
            public void Show<T, 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);
            }
        }
    
        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);
            }
        }
    View Code
                   {
                        Console.WriteLine("********************GenericMethod********************");
                        Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");
                        Type type = assembly.GetType("Ruanmou.DB.SqlServer.GenericMethod");
                        object oGeneric = Activator.CreateInstance(type);
                        //foreach (var item in type.GetMethods())
                        //{
                        //    Console.WriteLine(item.Name);
                        //}
                        MethodInfo method = type.GetMethod("Show");
                        var methodNew = method.MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });
                        object oReturn = methodNew.Invoke(oGeneric, new object[] { 123, "test", DateTime.Now });
                    }
                    {
                        Console.WriteLine("********************GenericMethod+GenericClass********************");
                        Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");
                        Type type = assembly.GetType("Ruanmou.DB.SqlServer.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, "teat", DateTime.Now });
    
                    }
    View Code

    反射破坏单例

        /// <summary>
        /// 单例模式:类,能保证在整个进程中只有一个实例
        /// </summary>
        public sealed class Singleton
        {
            private static Singleton _Singleton = null;
            private Singleton()
            {
                Console.WriteLine("Singleton被构造");
            }
    
            static Singleton()
            {
                _Singleton = new Singleton();
            }
    
            public static Singleton GetInstance()
            {
                return _Singleton;
            }
        }
    View Code
                      {
    
                        Console.WriteLine("********************Singleton********************");
                        Singleton singleton1 = Singleton.GetInstance(); //new Singleton();
                        Singleton singleton2 = Singleton.GetInstance();
                        Singleton singleton3 = Singleton.GetInstance();
                        Singleton singleton4 = Singleton.GetInstance();
                        Singleton singleton5 = Singleton.GetInstance();
                        Console.WriteLine($"{object.ReferenceEquals(singleton1, singleton5)}");
    
                        //反射破坏单例---就是发射调用私有构造函数
                        Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");
                        Type type = assembly.GetType("Ruanmou.DB.SqlServer.Singleton");
                        Singleton singletonA = (Singleton)Activator.CreateInstance(type, true);
                        Singleton singletonB = (Singleton)Activator.CreateInstance(type, true);
                        Singleton singletonC = (Singleton)Activator.CreateInstance(type, true);
                        Singleton singletonD = (Singleton)Activator.CreateInstance(type, true);
                        Console.WriteLine($"{object.ReferenceEquals(singletonA, singletonD)}");
                    }
    View Code

     本文参考文档:

    https://www.cnblogs.com/loverwangshan/p/9883243.html;

    微软文档地址:

    .NET Framework 中的反射:https://docs.microsoft.com/zh-cn/dotnet/framework/reflection-and-codedom/reflection;

    System.Reflection Namespace:https://docs.microsoft.com/zh-cn/dotnet/api/system.reflection?view=netframework-4.7.2;

    Type Class:https://docs.microsoft.com/zh-cn/dotnet/api/system.type?view=netframework-4.7.2;

  • 相关阅读:
    女程序员发的一条微博
    【转】Android中JNI的使用方法
    【转】浏览器~加载,解析,渲染
    【转】PHP简单拦截器的实现
    【转】jQuery选择器总结
    【转】JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)
    【转】JSONP跨域的原理解析
    utuntu16.04安装tensorflow1.4-gpu
    Kaggle-Digit Recognizer
    python 常见细节知识点
  • 原文地址:https://www.cnblogs.com/Dewumu/p/10513996.html
Copyright © 2011-2022 走看看