C#高级编程之反射
反射的定义
MSDN定义:反射提供描述程序集、模块和类型的对象(Type类型)。 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型,然后调用其方法或访问器字段和属性。 如果代码中使用了特性,可以利用反射来访问它们。
一共三句话。
第一句意思是可以利用反射提供的API来获取程序集信息,包括其下的模块、Type类型信息;
第二句意思通过反射,先拿到这个程序集->Module->Type的类型信息,然后调用实例化的API Activator.CreateInstance(type type)来实例化该类型对象,拿到对象instance后,可以对这个对象数据成员进行赋值,然后注入到现有对象B中;或者是利用API获取这个类型下的属性、方法等信息,对其进行读写、调用操作。
第三句意思是:如果反射获取到的这个类型有使用Attribute特性,可以进行互操作。
反射使用
反射一般使用过程如下:
装载程序集Assmebly
上面的方法讲的是反射AppDomain的所有程序集,我们可以显示的调用其中的一个程序集,system.reflecton.assembly 类型提供了下面三种方法:
1、Load 方法:极力推荐的一种方法,Load 方法带有一个程序集标志并载入它,Load 将引起CLR把策略应用到程序集上,先后在全局程序集缓冲区,应用程序基目录和私有路径下面查找该程序集,如果找不到该程序集系统抛出异常
2、LoadFrom 方法:传递一个程序集文件的路径名(包括扩展名),CLR会载入您指定的这个程序集,传递的这个参数不能包含任何关于版本号的信息,区域性,和公钥信息,如果在指定路径找不到程序集抛出异常。
3、LoadWithPartialName:永远不要使用这个方法,因为应用程序不能确定再在载入的程序集的版本。该方法的唯一用途是帮助那些在.Net框架的测试环节使用.net 框架提供的某种行为的客户,这个方法将最终被抛弃不用。
注意:system.AppDomain 也提供了一种Load 方法,他和Assembly的静态Load 方法不一样,AppDomain的load 方法是一种实例方法,返回的是一个对程序集的引用,Assembly的静态Load 方发将程序集按值封装发回给发出调用的AppDomain.尽量避免使用AppDomain的load 方法。
获取类型信息
//定义一个获取反射内容的方法
static void getreflectioninfo(Assembly myassembly)
{
Type[] typearr = myassembly.GetTypes();//获取类型
foreach (Type type in typearr)//针对每个类型获取详细信息
{
//获取类型的结构信息
ConstructorInfo[] myconstructors = type.GetConstructors(); //获取类型的字段信息
FieldInfo[] myfields = type.GetFields(); //获取方法信息
MethodInfo[] myMethodInfo = type.GetMethods(); //获取属性信息
PropertyInfo[] myproperties = type.GetProperties(); //获取事件信息
EventInfo[] Myevents = type.GetEvents();
}
}
调用普通类泛型方法
泛型方法签名:public void Show<T,W,X>(T t,W,w,X x);
Assembly assmebly=Assembly.Load("")
Type type=assembly.GetType("namespace.sqlServerHelper");
dbHeperInstace =Activator.CreateInstace(type)
MethodInfo genericMethod=type.GetMethod("show");
MethodInfo genericMethod1=genericMethod.MakeGenericMethod(new Type[]{typeof(int),typeof(string),typeof(DateTime)};
genericMethod1.invoke(dbHeperInstace,new object[]{123,"john",DateTime.Now};
调用泛型类里面泛型方法
【[此处的Show方法的具体参数的type类型依赖于class上的<T,W,X>]】eg.
class GenericClass<T,W,X>
{
public void Show<T,W,X>(T t,W,w,X x)
}
[占位符]
Type type=assembly.GetType("namespace.sqlServerHelper.GenericClass`3");
Type type1=type.MakeGenericType(new Type[]{typeof(int),typeof(string),typeof(DateTime)};
object GenericdbHeperInstace =Activator.CreateInstace(type1);
MethodInfo genericMethod=type1.GetMethod("show");
genericMethod.invoke(GenericdbHeperInstace,new object[]{123,"john",DateTime.Now});
反射设置属性值
对于属性的操作具体可以参考 https://blog.csdn.net/shuzhongke123/article/details/106091047
总结
反射特点:
动态 减少对象与对象之间的依赖,只需要知道类名,方法名就可以调用,还可以突破特定权限,可以做到普通方式无法做到的。
性能问题:经过缓存优化之后,是普通的10倍。对于性能损耗,请理性看待。
参考:https://www.cnblogs.com/wangshenhe/p/3256657.html
C#高级编程之反射的更多相关文章
- Atitit. 高级软件工程师and 普通的区别 高级编程的门槛总结
Atitit. 高级软件工程师and 普通的区别 高级编程的门槛总结 1. 完备的知识体系 2 2. 编程理论/原理的掌握 2 1.1. 掌握常用的概念(ORM,IOC,AOP,event driv ...
- C# 6 与 .NET Core 1.0 高级编程 - 38 章 实体框架核心(上)
译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 38 章 实体框架核心(上)),不对的地方欢迎指出与交流. 章节出自<Professional C# 6 ...
- C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(上)
译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(上)),不对的地方欢迎指出与交流. 章节出自<Professional C# ...
- C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(中)
译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(中)),不对的地方欢迎指出与交流. 章节出自<Professional C# ...
- C#高级编程笔记之第三章:对象和类型
类和结构的区别 类成员 匿名类型 结构 弱引用 部分类 Object类,其他类都从该类派生而来 扩展方法 3.2 类和结构 类与结构的区别是它们在内存中的存储方式.访问方式(类似存储在堆上的引用类型, ...
- 解读经典《C#高级编程》第七版 Page79-93.对象和类型.Chapter3
前言 本篇我们继续讲解本章其余的部分:构造函数.只读字段.匿名类型.结构详解.部分类.静态类.Object类.扩展方法,等. 01 类 构造函数 构造函数是一种特殊的方法: 与类同名 没有返回值,甚至 ...
- 解读经典《C#高级编程》第七版 Page68-79.对象和类型.Chapter3
前言 新年好,本篇开始进入第三章,<对象和类型>,深刻理解C#的对象,对于使用好.Net类库非常重要. 01 类和结构 从使用角度看,结构和类的区别很小,比如,将结构定义转换为类,只需要将 ...
- 解读经典《C#高级编程》第七版 Page45-50.核心C#.Chapter2
前言 本篇讲述枚举和名称空间. 01 枚举 首先需要明确枚举的概念:枚举是用户定义的整数类型.使用枚举的目标是,使用一组容易记忆的名称,来使得代码更容易编写和维护. 我们对比枚举的定义和类的定义,会发 ...
- 解读经典-《C#高级编程》第七版-Chapter1-.Net体系结构-Page13-20
01 程序集 程序集是包含编译好的.基于.Net Framework的代码逻辑单元.一般来说,在Visual Studio中的一个项目即一个程序集,而一个项目中包含多种不同的代码文件.程序集分为可执行 ...
随机推荐
- docker启动服务---------------mysql
1.查找镜像: docker search mysql 也可以去官网查看镜像tag,选择自己需要的版本,否则会下载最新版本:https://hub.docker.com/_/mysql/ 2.下载镜像 ...
- docker启动服务---------------elasticsearch
一 环境 vbox5.2.8 centos7 docker 19.03.1 elasticsearch 7.9.1 二 进入centos7启动dcoker systemctl start ...
- spring boot:使用poi导出excel电子表格文件(spring boot 2.3.1)
一,什么是poi? 1,poi poi是用来兼容微软文档格式的java api, 它是apache的顶级项目之一, 也是我们在生产环境中导出excel时使用最多的库 2,poi官方网站: http:/ ...
- S10 TES的八强赛,创造了奇迹,看看比赛时网友们怎么说的
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理 我相信很多观众会和我一样吧,当TES赢下第一局后开始心怀侥幸,赢下第二局后觉 ...
- ServletRequest使用介绍
ServletRequest: 定义将客户端请求信息提供给某个 servlet 的对象:servlet 容器创建 ServletRequest 对象,并将该对象作为参数传递给该servlet的serv ...
- ng中的ng-content ng-template ng-container
在angular中,有这样三个自带的标签,但是在angular的文档中没有说明,只有在api中有简单的描述,摸索了半天才搞懂是咋回事. ng-content <div> <ng-co ...
- javascript常见面试题之一:将字符串'get-element-by-id'转换成驼峰命名法;
var str='get-element-by-id'; function strToupper(str) { //利用split将字符串分割成数组var arr= str.split('-'); f ...
- 感知机vs支持向量机
感知机原理:二维空间中找到一条直线可以把所有二元类别分离开,三维或多维空间中,找到一个分离超平面把所有二元类别分离开.而可把所有二元类别分离开的超平面不止一个,哪个是最好的呢?损失函数:所有误分类的点 ...
- Java中的微信支付(2):API V3 微信平台证书的获取与刷新
1. 前言 在Java中的微信支付(1):API V3版本签名详解一文中胖哥讲解了微信支付V3版本API的签名,当我方(你自己的服务器)请求微信支付服务器时需要根据我方的API证书对参数进行加签,微信 ...
- Longest common subsequence(LCS)
问题 说明该问题在生物学中的实际意义 Biological applications often need to compare the DNA of two (or more) different ...