ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

.NET知识梳理——2.反射

2020-02-21 10:01:56  阅读:269  来源: 互联网

标签:反射 Assembly DB object XF NET Type 梳理 type2


 

1. 反射

1.1        DLL-IL-Metadata-反射

DLL:程序集,包含IL 和Metadada

IL:面向对象中间语言(不太好阅读)

Metadata描述了dll、exe中的各种类、属性、方法、参数等信息。

反射 Reflection: .NET Framework提供的帮助类库,可以读取Metadata。

C# 高级语言经过编译器编译生成DLL/EXE,DLL/EXE中包含了Metadata和IL,CLR先读取DLL/EXE中的Metadata,然后JIT进行二次编译,编译成机器码。

 

 

1.2        反射加载DLL,读取类、方法、特性

1.2.1  加载DLL

   Assembly assembly = Assembly.Load("XF.DB.SqlServer");//动态加载,需要提供完整的DLL名,不需要后缀,从exe所在的路径进行查找

   Assembly assembly2 = Assembly.LoadFile(@"C:\HXF_CODE\02.Code\05.NET Code\XF.High.NET.Study\XF.DB.SqlServer\bin\Debug\XF.DB.Sqlserver.dll");

   Assembly assembly3 = Assembly.LoadFrom("XF.DB.SqlServer.dll");

Assembly assembly4 = Assembly.LoadFrom(@"C:\HXF_CODE\02.Code\05.NET Code\XF.High.NET.Study\XF.DB.SqlServer\bin\Debug\XF.DB.Sqlserver.dll");

1.2.2  读取类并创建对象

  Type type = assembly.GetType("XF.DB.SqlServer.SqlServerHelper");//获取类型,需要提供完整的类型名称

                object sqlServerHelper = Activator.CreateInstance(type);

                IDBHelper dbHelper = sqlServerHelper as IDBHelper;

                dbHelper.Query();

  2.2.创建多构造函数对象:

object ctor1 = Activator.CreateInstance(type);

                object ctor2 = Activator.CreateInstance(type, new object[] { 123 });

                object ctor3 = Activator.CreateInstance(type, new object[] { "Olive" });

1.3        反射创建对象,反射+简单工厂+配置文件 

程序可配置,通过配置文件自动切换

实现类必须是事先已有的,且存在运行目录下

没有写死类型,通过配置文件执行,反射创建

可扩展:不修改原有代码,只是增加新的实现,修改配置即可支持新功能

反射动态加载、创建对象,与配置文件结合。

private static string typeStr = ConfigurationManager.AppSettings["IDBHelperConfig"];

//反射动态加载、创建对象结合配置文件

            {

                string[] typeArr = typeStr.Split(',');

                Assembly assembly1 = Assembly.Load(typeArr[1]);

                Type type = assembly1.GetType(typeArr[0]);

                foreach (var ctor in type.GetConstructors())

                {

                    Console.WriteLine(ctor.Name);

                    foreach (var parameter in ctor.GetParameters())

                    {

                        Console.WriteLine(parameter.ParameterType);

                    }

                }

 

                object ctor1 = Activator.CreateInstance(type);

                object ctor2 = Activator.CreateInstance(type, new object[] { 123 });

                object ctor3 = Activator.CreateInstance(type, new object[] { "Olive" });

            }

1.4        选修:破坏单例 创建泛型

1.4.1 反射破坏单例

反射破坏单例(调用私有的构造函数)

//反射破坏单例(调用私有的构造函数)

                Assembly assembly5 = Assembly.Load("XF.DB.SqlServer");

                Type type1 = assembly.GetType("XF.DB.SqlServer.Singleton");

                Singleton singleton4 = (Singleton)Activator.CreateInstance(type1, true);

                Singleton singleton5 = (Singleton)Activator.CreateInstance(type1, true);

                Singleton singleton6 = (Singleton)Activator.CreateInstance(type1, true);

                Console.WriteLine($"{object.ReferenceEquals(singleton4, singleton6)}");

1.4.2 反射创建泛型

 

   Assembly assembly6 = Assembly.Load("XF.DB.SqlServer");

                Type type2 = assembly.GetType("XF.DB.SqlServer.GenericClass`3");//`3为类型占位符,有几个类型就是几,这里有3个类型

                Type typeMake = type2.MakeGenericType(new Type[] { typeof(string), typeof(int), typeof(DateTime) });//确定泛型的类型

                object genericInstance = Activator.CreateInstance(typeMake);//在创建实例的时候,一定要明确具体的类型

                GenericClass<string,int,DateTime> gc = genericInstance as GenericClass<string, int, DateTime>;

                gc.Show("Olive", 116, DateTime.Now);

1.5        反射调用实例方法、静态方法、重载方法

1.5.1  反射调用实例方法

Assembly assembly6 = Assembly.Load("XF.DB.SqlServer");

                Type type2 = assembly6.GetType("XF.DB.SqlServer.ReflectionTest");

                object test = Activator.CreateInstance(type2);

 

                MethodInfo method = type2.GetMethod("Show");//调用无参函数

                method.Invoke(test, null);

 

                MethodInfo method1 = type2.GetMethod("Show1");//调用有参函数

                method1.Invoke(test,new object[] { "Olive" });

1.5.2  反射调用静态方法

 

Assembly assembly6 = Assembly.Load("XF.DB.SqlServer");

                Type type2 = assembly6.GetType("XF.DB.SqlServer.ReflectionTest");

                object test = Activator.CreateInstance(type2);

  MethodInfo method6 = type2.GetMethod("Show4");//调用静态函数,实例可要

                method6.Invoke(test, new object[] { "Olive" });

 

                MethodInfo method7 = type2.GetMethod("Show4");//调用静态函数,实例为空

                method7.Invoke(null, new object[] {  "Olive" });

1.5.3  反射调用重载方法

 

Assembly assembly6 = Assembly.Load("XF.DB.SqlServer");

                Type type2 = assembly6.GetType("XF.DB.SqlServer.ReflectionTest");

                object test = Activator.CreateInstance(type2);

MethodInfo method2 = type2.GetMethod("Show2", new Type[] {  });//调用重载函数,无参

                method2.Invoke(test, null);

 

                MethodInfo method3 = type2.GetMethod("Show2", new Type[] {typeof(int) });//调用重载函数

                method3.Invoke(test, new object[] { 116 });

 

                MethodInfo method4 = type2.GetMethod("Show2", new Type[] {typeof(string),typeof(int) });//调用重载函数

                method4.Invoke(test, new object[] { "Olive",116 });

 

                MethodInfo method5 = type2.GetMethod("Show2", new Type[] { typeof(int) ,typeof(string)});//调用重载函数

                method5.Invoke(test, new object[] { 116,"Olive" });

1.6        调用私有方法 调用泛型方法

1.6.1  反射调用私有方法

 

  Assembly assembly6 = Assembly.Load("XF.DB.SqlServer");

                Type type2 = assembly6.GetType("XF.DB.SqlServer.ReflectionTest");

                object test = Activator.CreateInstance(type2);

MethodInfo method8 = type2.GetMethod("Show3",BindingFlags.Instance|BindingFlags.NonPublic);//调用私有函数

                method8.Invoke(test, new object[] { "Olive" });

1.6.2  反射调用泛型方法

  Assembly assembly6 = Assembly.Load("XF.DB.SqlServer");

                Type type2 = assembly6.GetType("XF.DB.SqlServer.GenericMethod");

                object test = Activator.CreateInstance(type2);

 

                MethodInfo method = type2.GetMethod("Show");//调用无参函数

                var methodNew = method.MakeGenericMethod(new Type[] { typeof(string), typeof(int), typeof(DateTime) });

 

                methodNew.Invoke(test,new object[] { "Olive", 116, DateTime.Now });

1.6.3  反射调用泛型类型+泛型方法

 

Type type2 = assembly6.GetType("XF.DB.SqlServer.GenericDouble`1");

                Type type3 = type2.MakeGenericType(new Type[] { typeof(int) });

 

                object test = Activator.CreateInstance(type3);

 

                MethodInfo method = type3.GetMethod("Show");

                var methodNew = method.MakeGenericMethod(new Type[] { typeof(string),  typeof(DateTime) });

 

                methodNew.Invoke(test, new object[] { 116, "Olive", DateTime.Now });

1.7        反射字段和属性,分别获取值和设置值

1.7.1  反射字段、获取、设置值

Assembly assembly6 = Assembly.Load("XF.Model");

                Type type = assembly6.GetType("XF.Model.People");

                object people = Activator.CreateInstance(type);

                foreach(var field in type.GetFields())

                {

                    Console.WriteLine($"{type.Name}.{field.Name}={field.GetValue(people)}");

                    if (field.Name.Equals("Description"))

                        field.SetValue(people, "Good boy");

                }

1.7.2  反射属性、获取、设置值

 

  Assembly assembly6 = Assembly.Load("XF.Model");

                Type type = assembly6.GetType("XF.Model.People");

                object people = Activator.CreateInstance(type);              

 

                foreach(var prop in type.GetProperties())

                {

                    Console.WriteLine($"{type.Name}.{prop.Name}={prop.GetValue(people)}");

                    if (prop.Name.Equals("Id"))

                        prop.SetValue(people, 116);

                }

1.8        反射的好处和局限

好处:动态

局限:使用麻烦

避开编译器检查

性能问题:正常情况下基本上不存在性能问题

标签:反射,Assembly,DB,object,XF,NET,Type,梳理,type2
来源: https://www.cnblogs.com/Olive116/p/12340323.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有