2语法基础_反射,表达式目录树
什么反射:1.通过微软提供的类,让我们可以直接在代码里面访问已经编译好的DLL
2.在c#编码中 想动态=反射+配置文件
ORM:就是在c#里面把数据库的表直接当做对象来操作使用
1:反射的定义:微软提供的一个帮助类库,为了让我们不用在vs里面添加引用从而直接动态加载dll 去用里面的方法
2:反射的应用领域:MVC AOP IOC ORM Attribute 都是使用了反射
反射特点:
动态 减少对象和对象之间的依赖,只需要知道类名(字符串)、方法名(字符串),就可以调用,
还可以突破特定权限,可以做到普通方式无法做到的
编写比较困难,代码量大,编写的时候容易出错
性能问题,性能损耗大, 可以进行缓存优化,但是还是会相差十多倍的性能
3:表达式目绿树本质就是一种数据结构(二叉树),如m*n+2+x 会从右往左拆分成 >(M*n+2)+x>(M*n)+2>M*n
拉姆达表达式是作为委托的一个参数,本质就是一个匿名方法,它只不过是可以快捷的声明表达式目绿树
表达式目录树的作用:
1.SQL查询语句拼接, (之前写sql查询条件都是根据一个个条件进行判断拼接,) 使用表达式目录树可以动态拼接
2.类与类之间的转换,使用表达式目录树把A类变成一个新的B类(结构要相同)
一般实现方法:1.硬编码(写死),2.json序列化,3.表达式目录树
3.使用表达式目录树动态转换类,和硬编码性能几乎没啥差距
(这里使用反射还有性能问题) 使用反射获取到A类的属性和字段, 用表达式目录树拼接好一个新的B类
然后使用委托执行B类,
(使用泛型泛型解决反射性能问题)最后使用泛型缓存 存储每个执行的委托(泛型缓存:为每个不同类型生成副本,所以不同类型只需要执行一次委托,后面就直接从缓存里面取)
这样性能高,扩展性好,又解决了反射的性能问题,
4:使用反射创建对象:反射+简单工厂+配置文件 实现简单数据库访问
Console.WriteLine("最基本使用反射调用类方法"); // 1、动态加载 Assembly assembly = Assembly.Load("类库");// dll名称 默认到当前目录下查找 //2、获取类型 Type type = assembly.GetType("类库.类"); //3、创建对象 object oDbHelper = Activator.CreateInstance(type); dynamic dDbHelper = Activator.CreateInstance(type); dDbHelper.Query(); //dynamic 是一个动态类型,可以避开编译器的检查,运行时检查 存在安全问题 因为c#是强类型语言,一般在编译时就会检测 //4、类型转换 IDBHelper iDBHelper = oDbHelper as IDBHelper; //5、调用方法 iDBHelper.Query();
Assembly assembly = Assembly.Load("类库"); Type type = assembly.GetType("类库.类名"); object oTest = Activator.CreateInstance(type); MethodInfo show1 = type.GetMethod("Show1"); //得到方法 //调用方法为什么一定要类型转换? //需要先获取方法,然后方法Invoke show1.Invoke(oTest, new object[0]);// 反射调用方法
//泛型编译之后生成占位符 `1 `2 `3 //正常调用 GenericMethod genericMethod = new GenericMethod(); genericMethod.Show<int, string, DateTime>(1234, "", DateTime.Now); //使用反射调用 Assembly assembly = Assembly.Load("类库"); Type type = assembly.GetType("类库.类名"); 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, "11", DateTime.Now }); // 传入参数必须和声明的一样
private static string Customers = ConfigurationManager.ConnectionStrings["Customers"].ToString(); /// <summary> /// 泛型方法 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="id"></param> /// <returns></returns> public static T Find<T>(int id) { //string sql = @"SELECT [Id] // ,[Name] // ,[CreateTime] // ,[CreatorId] // ,[LastModifierId] // ,[LastModifyTime] // FROM [SystemDB].[dbo].[Company] where Id=" + id; Type type = typeof(T); object oCompany = Activator.CreateInstance(type); //List<string> var propNames = type.GetProperties().Select(a => $"[{a.Name}]"); string props = string.Join(",", propNames); string sql = $"SELECT {props } FROM [{type.Name}] where Id={id}"; using (SqlConnection connection = new SqlConnection(Customers)) { SqlCommand sqlCommand = new SqlCommand(sql, connection); connection.Open(); SqlDataReader reader = sqlCommand.ExecuteReader(); if (reader.Read()) //开始读取 { foreach (var prop in type.GetProperties()) { prop.SetValue(oCompany, reader[prop.Name]); } } } return (T)oCompany; }
Assembly assembly = Assembly.Load("类库"); Type type = assembly.GetType("类库。类名"); //Activator.CreateInstance 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 }); }
本文来自博客园,作者:12不懂3,转载请注明原文链接:https://www.cnblogs.com/LZXX/p/12957296.html