C# 进阶 反射

exe/dll(主要区别就是exe文件有入口)---metadata(元数据:描述exe/dll文件的一个数据清单)--反射(Reflection)用来操作获取元数(metadata)
【1】更新程序时(更新自己的DLL)
【2】使用别人的DLL文件(这种可以读取别人的私有的东西)

反射是什么?:他就是一个操作metadata的一个类库(可以把反射当成一个小工具用来读取或者操作元数据的)
类、方法、特性、属性字段。(为什么要通过反射间接去操作,1--因为我们需要动态,2--读取私有的对象)
那些地方使用到了:asp.net MVC ----ORM---LOC---AOP 几乎所有裤架都会使用反射。
反射---反射工具---操作metadata(元数据)的工具
通过反射加载DLL文件

 

 加载DLL文件

{
                    //Console.WriteLine("----------------------------------------Reflection--------------------------------");
                  Assembly assembly = Assembly.Load("Ant.DB.SQLServer");//加载方式一:dll文件名(当前目录)
                  Assembly assembly = Assembly.LoadFile(@"C:\Users\Administrator\Desktop\奇艺教程\C#语法进阶\MyReflection\Ant.DB.MySql\bin\Debug\Ant.DB.Interface.dll");//加载方式二:完整路径(文件具体路径)
                  Assembly assembly = Assembly.LoadFrom("Ant.DB.SQLServer.dll");//方法三:完全限定名(当前目录)
                  Assembly assembly = Assembly.LoadFrom(@"C:\Users\Administrator\Desktop\奇艺教程\C#语法进阶\MyReflection\Ant.DB.MySql\bin\Debug\Ant.DB.Interface.dll");//(文件具体路径)

                  foreach (var type in assembly.GetTypes())//找到所有类型
                  {
                      Console.WriteLine(type.Name);

                     foreach (var method in type.GetMethods())//类型下面的所有方法
                      {
                          Console.WriteLine("这是" + method.Name + "方法");
                       }
                   }

                }

通过反射创建对象

                {

                    Console.WriteLine("************************UseReflection 使用反射创建对象************************");
                    Assembly assembly = Assembly.LoadFrom("Ant.DB.SQLServer.dll");//【1】加载DLL文件
                    Type type = assembly.GetType("Ant.DB.SQLServer.SQLServerHelper");//【2】获取类型(要完整类型名称)
                    object oDbHelper = Activator.CreateInstance(type);//创建对象
                    SQLServerHelper sqlHelper = new SQLServerHelper();
                    IDBHelper dBHelper = oDbHelper as IDBHelper;//类型转换(as转换不报错,类型不对就返回null)
                    IDBHelper dBHelper2 = (IDBHelper)oDbHelper;
                    dBHelper.Query();

                }
使用反射创建对象(带参数的构造函数)
                
                {

                    Console.WriteLine("************************cotr&Parameter************************");
                    Assembly assembly = Assembly.LoadFrom("Ant.DB.SQLServer.dll");
                    Type type = assembly.GetType("Ant.DB.SQLServer.ReflectionTest");
                    //获取到这个类型下面所有构造方法
                    foreach (ConstructorInfo ctor in type.GetConstructors())//获取到所有的构造 方法
                    {
                        Console.WriteLine(ctor.Name);
                        foreach (var parameter in ctor.GetParameters())//获取到构造方法的所有参数类型
                       {
                            Console.WriteLine(parameter.ParameterType);//显示类型名称
                       }
                    }
                    Console.WriteLine("************************创建对象************************");
                    object oCotr1 = Activator.CreateInstance(type);//无参数构造函数
                    object oCotr2 = Activator.CreateInstance(type, new object[] { "Ant编程" });
                    object oCotr3 = Activator.CreateInstance(type, new object[] { 123 });
                    object oCotr3 = Activator.CreateInstance(type, new object[] { 123, "ant编程" });
                }

使用反射创建对象(私有构造函数)

                {
                    //这个功能 还用在我们的单例模式里面(一个对象只能创建一次),这个也叫反射破坏单例
                    Console.WriteLine("************************ctor&Private************************");
                    //PrivateCtor privateCtor = new PrivateCtor();
                    Assembly assembly = Assembly.LoadFrom("Ant.DB.SQLServer.dll");//加载DLL文件
                    Type type = assembly.GetType("Ant.DB.SQLServer.PrivateCtor");//获取到类型
                    object oPrivate = Activator.CreateInstance(type, true);
                }

使用反射创建泛型类

public class GenericClass<T, W, S>
    {
        public void Test<X, Y, Z>(X x, Y y, Z z)
        {
            Console.WriteLine("第一个类型是={0},第二个类型是={1},第三个类型是={2}", x.GetType().Name, y.GetType().Name, z.GetType().Name);
        }
    }
            Console.WriteLine("************************Generic&Class************************");
                    Assembly assembly = Assembly.LoadFrom("Ant.DB.SQLServer.dll");//获取DLL文件
                    Type type = assembly.GetType("Ant.DB.SQLServer.GenericClass`3");//获取到类型名称 
                    Type makeType = type.MakeGenericType(new Type[] { typeof(int), typeof(string), typeof(double) });//获取参数类型
                    object oGeneric = Activator.CreateInstance(makeType);
                

通过反射调用方法

                {
                    //这个第二种调用方法的方式:通过反向调用
                    Console.WriteLine("************************Method&Reflection************************");
                    Assembly assembly = Assembly.LoadFrom("Ant.DB.SQLServer.dll");//获取DLL文件
                    Type type = assembly.GetType("Ant.DB.SQLServer.ReflectionTest");//获取到类型名称 
                    object oReflection = Activator.CreateInstance(type);
                    //搜索所有的方法和方法名
                    foreach (var method in type.GetMethods())
                    {
                        Console.WriteLine(method.Name);
                        foreach (var parameter in method.GetParameters())
                        {
                            Console.WriteLine(parameter.Name + " " + parameter.ParameterType);
                        }
                    }
                    {
                        //调用无参数方法
                        MethodInfo methodInfo = type.GetMethod("Test1");//把Test1方法存储起来
                        methodInfo.Invoke(oReflection, null);//调用方法
                    }
                    {
                        //调用带参数方法
                        MethodInfo methodInfo = type.GetMethod("Test2");
                        methodInfo.Invoke(oReflection, new object[] { 123456 });//调用方法
                    }
                    //有参数重载方法
                    {
                       MethodInfo methodInfo = type.GetMethod("Test3", new Type[] { typeof(int), typeof(string) });
                       methodInfo.Invoke(oReflection, new object[] { 133, "Ant编程" });//调用方法
                    }
                    {
                        MethodInfo methodInfo = type.GetMethod("Test3", new Type[] { typeof(string), typeof(int) });
                        methodInfo.Invoke(oReflection, new object[] { "Ant编程", 133 });//调用方法
                    }
                    {

                        MethodInfo methodInfo = type.GetMethod("Test3", new Type[] { typeof(int) });
                        methodInfo.Invoke(oReflection, new object[] { 133 });//调用方法
                    }
                    {

                        MethodInfo methodInfo = type.GetMethod("Test3", new Type[] { typeof(string) });
                        methodInfo.Invoke(oReflection, new object[] { "Ant编程" });//调用方法
                    }
                    //无参数重载方法
                    {
                        MethodInfo methodInfo = type.GetMethod("Test3", new Type[] { });
                        methodInfo.Invoke(oReflection, null);//调用方法
                    }
                    //静态方法的调用 方式一
                    {
                        MethodInfo methodInfo = type.GetMethod("Test5");
                        methodInfo.Invoke(oReflection, new object[] { "Ant编程" });//调用方法
                    }
                    //静态方法的调用 方式二
                    {
                        MethodInfo methodInfo = type.GetMethod("Test5");
                        methodInfo.Invoke(null, new object[] { "Ant编程" });//调用方法
                    }
                   
                }

通过反射调用私有方法

{

                    Console.WriteLine("************************PrivateMethod&Reflection************************");
                    Assembly assembly = Assembly.LoadFrom("Ant.DB.SQLServer.dll");//获取DLL文件
                    Type type = assembly.GetType("Ant.DB.SQLServer.ReflectionTest");//获取到类型名称 
                    object oReflection = Activator.CreateInstance(type);
                    MethodInfo methodInfo = type.GetMethod("Test4", BindingFlags.Instance | BindingFlags.NonPublic);
                    methodInfo.Invoke(oReflection, new object[] { "Ant编程" });
                }

通过反射调用泛型方法(普通类里面的泛型方法调用)

{
                    Console.WriteLine("************************GenericMethod************************");
                    Assembly assembly = Assembly.LoadFrom("Ant.DB.SQLServer.dll");//获取DLL文件
                    Type type = assembly.GetType("Ant.DB.SQLServer.GenericMethod");//获取到类型名称 
                    object oReflection = Activator.CreateInstance(type);//实例化类型
                    MethodInfo methodInfo = type.GetMethod("Test");//找到要调用的方法
                    MethodInfo methodGeneric = methodInfo.MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });//确定方法的参数类型和个数
                    methodGeneric.Invoke(oReflection, new object[] { 1, "Ant编程", DateTime.Now });
                }

 

 

 public class GenericClass<T, W, S>
    {
        public void Test<X, Y, Z>(X x, Y y, Z z)
        {
            Console.WriteLine("第一个类型是={0},第二个类型是={1},第三个类型是={2}", x.GetType().Name, y.GetType().Name, z.GetType().Name);
        }
    }


{

                    Console.WriteLine("*****************GenericMethod+GenericClass***************");
                    Assembly assembly = Assembly.LoadFrom("Ant.DB.SQLServer.dll");//获取DLL文件
                    Type type = assembly.GetType("Ant.DB.SQLServer.GenericClass`3");//获取到类型名称 
                    Type typeNew = type.MakeGenericType(new Type[] { typeof(int), typeof(string), typeof(DateTime) });//确定泛型方法的参数类型
                    object oReflection = Activator.CreateInstance(typeNew);//实例化类型
                    MethodInfo methodInfo = typeNew.GetMethod("Test");//找到方法
                    MethodInfo methodInfoNew = methodInfo.MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });
                    methodInfoNew.Invoke(oReflection, new object[] { 1, "Ant编程", DateTime.Now });


                    Console.WriteLine("*****************GenericMethod+GenericClass***************");
                    Assembly assembly = Assembly.LoadFrom("Ant.DB.SQLServer.dll");//获取DLL文件
                    Type type = assembly.GetType("Ant.DB.SQLServer.GenericClass`3").MakeGenericType(new Type[] { typeof(int), typeof(string), typeof(DateTime) });//获取到类型名称 
                    Type typeNew = type.MakeGenericType(new Type[] { typeof(int), typeof(string), typeof(DateTime) });//确定泛型方法的参数类型
                    object oReflection = Activator.CreateInstance(type);//实例化类型
                    MethodInfo methodInfo = type.GetMethod("Test").MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) }); ;//找到方法
                    MethodInfo methodInfoNew = methodInfo.MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });
                    methodInfo.Invoke(oReflection, new object[] { 1, "Ant编程", DateTime.Now });

                }

通过反射操作字段和属性等成员

                {
                    //Student studen = new Student()
                    //{
                    //    Id = 1,
                    //    StudentAddress = "小琳",
                    //    StudentName = "北京"
                    //};

                    ////反射方式
                    Assembly assembly = Assembly.LoadFrom("Ant.DB.SQLServer.dll");//获取到DLL信息
                    Type type = assembly.GetType("Ant.DB.SQLServer.Student");//找到需要操作的对象类型
                    object oStudent = Activator.CreateInstance(type);//创建对象
                    //方式一
                    foreach (var prop in type.GetProperties())
                    {
                        Console.WriteLine($"{prop.PropertyType}+{prop.Name}={prop.GetValue(studen)}");
                        Console.WriteLine("-------------------------------------------------");
                        if (prop.Name.Equals("Id"))
                        {
                            prop.SetValue(studen, 2);
                        }
                        if (prop.Name.Equals("StudentName"))
                        {
                            prop.SetValue(studen, "小董");
                        }
                        if (prop.Name.Equals("StudentAddress"))
                        {
                            prop.SetValue(studen, "武汉");
                        }
                        Console.WriteLine($"{prop.PropertyType}+{prop.Name}={prop.GetValue(studen)}");
                    }
                    ////方式二
                    PropertyInfo[] propertyInfos = type.GetProperties();//查找所有的属性
                    PropertyInfo propertyInfo = type.GetProperty("Id");
                    //用反射来操作字段(作业)
                }

 

posted @ 2021-02-28 21:13  KnowledgePorter  阅读(26)  评论(0)    收藏  举报