(精华)2020年8月9日 C#基础知识点 反射

(精华)2020年8月9日 C#基础知识点 反射

原理图
在这里插入图片描述

/// <summary>
    /// 1 dll-IL-metadata-反射
    /// 2 反射加载dll,读取module、类、方法
    /// 3 反射创建对象,反射+简单工厂+配置文件 ,破坏单例 创建泛型
    /// 反射反射程序员的快乐
    /// 反射是无处不在,MVC  AOP  IOC  ORM  Attribute 
    /// IL:中间语言,标准的面向对象语言,但是不太好阅读
    /// metadata:元数据, 数据清单,只是描述了类中有什么
    /// 反射:Reflection, System.Reflection命名空间,是微软提供的一个帮助类库
    /// </summary>
    class Program
    {<!-- -->
        static void Main(string[] args)
        {<!-- -->
            try
            {<!-- -->
                #region 反射的基本使用
                {<!-- -->
                    //-------------------------- 1、动态加载(获取程序集的数据)--------------------------
                    Assembly assembly = Assembly.Load("DB.SqlServer");// dll名称  默认到当前目录下查找
                    Assembly assembly1 = Assembly.LoadFile(@"D:\MyReflection\bin\Debug\DB.SqlServer.dll");// 全名称= 全路径+dll名称 + 后缀
                    Assembly assembly2 = Assembly.LoadFrom("DB.SqlServer.dll");// 全名称
                    Assembly assembly3 = Assembly.LoadFrom(@"D:\MyReflection\bin\Debug\DB.SqlServer.dll");// 全名称
                    foreach (Type type in assembly.GetTypes())
                    {<!-- -->
                        Console.WriteLine(type.Name);
                        foreach (MethodInfo method in type.GetMethods())
                        {<!-- -->
                            Console.WriteLine(method.Name);
                        }
                    }
                }
                {<!-- -->
                    //------------------------1、动态加载(使用程序集的数据创建实例和使用)-----------------------------
                    Assembly assembly = Assembly.Load("DB.SqlServer");// dll名称  默认到当前目录下查找
                    //2、获取类型
                    Type type = assembly.GetType("DB.SqlServer.SqlServerHelper");
                    //3、创建对象
                    object oDbHelper = Activator.CreateInstance(type);
                    //oDbHelper.Query();//  编译器就不认可  c# 是强类型语言,不能Query 
                    //dynamic dDbHelper = Activator.CreateInstance(type);
                    //dDbHelper.Query(); //dynamic 是一个动态类型,可以避开编译器的检查,运行时检查  存在安全问题 
                    //4、类型转换
                    IDBHelper iDBHelper = oDbHelper as IDBHelper;
                    //5、调用方法
                    iDBHelper.Query();
                }
                {<!-- -->   //---------------------------用工厂创建实例---------------------------
                    IDBHelper iDBHelper = SimlpFactory.CreateInstentce();
                    iDBHelper.Query();
                } 
                {<!-- -->
                    //-------------------------反射选择不同的构造函数创建对象----------------------
                    Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");
                    Type type = assembly.GetType("Ruanmou.DB.SqlServer.ReflectionTest");
                    object oDbHelper = Activator.CreateInstance(type);
                    object oDbHelper1 = Activator.CreateInstance(type, new object[] {<!-- --> "杰克" });
                    object oDbHelper2 = Activator.CreateInstance(type, new object[] {<!-- --> "我是谁" });
                    object oDbHelper3 = Activator.CreateInstance(type, new object[] {<!-- --> 123 });
                }
                {<!-- -->
                    //--------------------反射需要先获取方法,然后方法Invoke--------------------
                    Assembly assembly = Assembly.Load("DB.SqlServer");
                    Type type = assembly.GetType("DB.SqlServer.ReflectionTest");
                    object oTest = Activator.CreateInstance(type);
                    MethodInfo show1 = type.GetMethod("Show1");
                    show1.Invoke(oTest, new object[0]);// 反射调用方法 
                    MethodInfo show2 = type.GetMethod("Show2");
                    show2.Invoke(oTest, new object[] {<!-- --> 123 });// 反射调用方法 ,需要参数的时候,参数类型必须和方法参数类型保持一致
                    //重载方法:
                    MethodInfo show3 = type.GetMethod("Show3", new Type[] {<!-- --> typeof(string), typeof(int) });
                    show3.Invoke(oTest, new object[] {<!-- --> "飞哥", 134 });// 反射调用方法 

                    MethodInfo show4 = type.GetMethod("Show4", BindingFlags.NonPublic | BindingFlags.CreateInstance);
                    show4.Invoke(oTest, new object[] {<!-- --> "Tenk" });// 反射调用方法 

                    MethodInfo show5 = type.GetMethod("Show5");
                    show5.Invoke(oTest, new object[] {<!-- --> "彭于晏" });// 反射调用静态方法: 对象的实例  可以传入,也可以传入null
                    show5.Invoke(null, new object[] {<!-- --> "Korey" });
                }
                {<!-- -->
                    //---------------反射调用泛型相关------------------------------
                    //泛型编译之后生成展位符  `1   `2    `3
                    Assembly assembly = Assembly.Load("DB.SqlServer");
                    Type type = assembly.GetType("DB.SqlServer.GenericMethod");
                    object oTest = Activator.CreateInstance(type);
                    MethodInfo genericMethod = type.GetMethod("Show");
                    MethodInfo genericMethod1 = genericMethod.MakeGenericMethod(new Type[] {<!-- --> typeof(int), typeof(string), typeof(DateTime) });// 指定泛型方法的  具体参数 
                    genericMethod1.Invoke(oTest, new object[] {<!-- --> 123, "jun", DateTime.Now }); // 传入参数必须和声明的一样
                    //在泛型类中 调用泛型方法
                    Assembly assembly = Assembly.Load("DB.SqlServer");
                    Type type = assembly.GetType("DB.SqlServer.GenericClass`3"); //获取一个泛型类型 
                                                                                 // GenericClass<int,string,DateTime> genericClass = new GenericClass<int, string, DateTime>()
                    Type type1 = type.MakeGenericType(new Type[] {<!-- --> typeof(int), typeof(string), typeof(DateTime) });
                    object oGenericTest = Activator.CreateInstance(type1);
                    MethodInfo genericMethod = type1.GetMethod("Show");
                    genericMethod.Invoke(oGenericTest, new object[] {<!-- --> 123, "零零", DateTime.Now });
                }
                {<!-- -->
                    //-----------------反射破坏单利  其实就是反射调用私有构造函数-------------------
                    Singleton singleton = new Singleton();
                    Singleton singleton1 = Singleton.GetInstance();
                    Singleton singleton2 = Singleton.GetInstance();
                    Singleton singleton3 = Singleton.GetInstance();
                    Singleton singleton4 = Singleton.GetInstance();
                    Console.WriteLine(singleton1.Equals(singleton4));

                    Assembly assembly = Assembly.Load("DB.SqlServer");
                    Type type = assembly.GetType("DB.SqlServer.Singleton");
                    object oSingleton1 = Activator.CreateInstance(type, true); //完全等价于 New Singleton
                    object oSingleton2 = Activator.CreateInstance(type, true);
                    object oSingleton3 = Activator.CreateInstance(type, true);
                    object oSingleton4 = Activator.CreateInstance(type, true);
                    Console.WriteLine(oSingleton1.Equals(oSingleton4));
                }
                 {<!-- -->
                        //-----------------------反射使用属性字段----------------
                        People people = new People();
                        people.Id = 123;
                        people.Name = "零零";
                        people.Description = "啦啦啦";
                        Console.WriteLine($"people.Id={people.Id}");
                        Console.WriteLine($"people.Name={people.Name}");
                        Console.WriteLine($"people.Description={people.Description}");
                        // 1、GetValue其实是有意义的
                        // 2、SetValue 好像没啥用
                        Type type = typeof(People);
                        object oPeople = Activator.CreateInstance(type);
                        foreach (PropertyInfo prop in type.GetProperties())
                        {<!-- -->
                            if (prop.Name.Equals("Id"))
                            {<!-- -->
                                prop.SetValue(oPeople, 123);
                            }
                            else if (prop.Name.Equals("Name"))
                            {<!-- -->
                                prop.SetValue(oPeople, "零零");
                            }
                            Console.WriteLine($"oPeople.{prop.Name}={prop.GetValue(oPeople)}");
                        }

                        foreach (FieldInfo field in type.GetFields())
                        {<!-- -->
                            if (field.Name.Equals("Description"))
                            {<!-- -->
                                field.SetValue(oPeople, "啦啦啦");
                            }
                        }
                    }
                #endregion
            }
            catch (Exception ex)
            {<!-- -->
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }
    }
    public class SimlpFactory
    {<!-- -->
        private static string IDBHelperConfig = ConfigurationManager.AppSettings["IDBHelperConfig"];
        private static string DllName = IDBHelperConfig.Split(',')[1];
        private static string TypeName = IDBHelperConfig.Split(',')[0];
        public static IDBHelper CreateInstentce()
        {<!-- -->
            Assembly assembly = Assembly.Load(DllName);
            Type type = assembly.GetType(TypeName);
            object oDbHelper = Activator.CreateInstance(type);
            return oDbHelper as IDBHelper;
        }
    }
posted @ 2020-12-30 11:45  不要摸我的腰  阅读(94)  评论(0编辑  收藏  举报