C#基础之反射
虽然还在学校读书,反射实际写的不多。但感觉反射在程序开发中用得还是挺多的,对我来说也是.NET中的一个难点。通过反射,我们可以在运行时获得.NET中的每一个类型的成员,这些类型包括类、结构、委托和枚举。有了反射,即可对每一个类型了如指掌。只要获得了构造函数的信息,即可直接创建对象,即使这个对象的类型在编译时还不知道。
1.一个反射的例子
我们建立一个类库ClassPeople和一个控制台应用程序CA,下面的代码是ClassPeople类库里的People类和Man类
public class People
{
private string name = null;
public People() { }
public People(string strName)
{
name = strName;
}
public void Say()
{
if (name == null)
{
Console.WriteLine("hi~~");
}
Console.WriteLine("hi"+name);
}
}
public class Man
{
void Eat(){ Console.WriteLine("EAT"); }
}
下面的代码为CA项目里的Main方法。
static void Main(string[] args)
{
Type people=null;
//注意:执行这句代码时要将ClassPeople.dll复制到Debug目录下,这样才能找到这个文件
Assembly ass = Assembly.LoadFrom("ClassLibrary1.dll");
Type[] mytypes = ass.GetTypes();
Console.WriteLine("列出程序集中的所有类型");
foreach (Type t in mytypes)
{
Console.WriteLine(t.Name);
if (t.Name == "People")
{
people = t;
}
}
Console.WriteLine("列出People类中的方法:");
MethodInfo[] methodInfo = people.GetMethods();
foreach (MethodInfo mi in methodInfo)
{
Console.WriteLine(mi.Name);
}
//实例化People,并调用Say方法
Object obj = Activator.CreateInstance(people);
Object objName = Activator.CreateInstance(people, "kobe");
MethodInfo minfo = people.GetMethod("Say");
Console.WriteLine("调用Say方法");
minfo.Invoke(obj, null);
minfo.Invoke(objName, null);
Console.ReadLine();
}
2.反射常用类与方法
Assembly:通过这个类可以加载操纵一个程序集,并获取程序集内部信息。
EventInfo:这个类保存给定的事件信息。
FieldInfo:保存给定的字段信息。
MethodInfo:保存给定的方法信息。
ParameterInfo:保存参数信息。
PropertyInfo:保存属性信息。
Module:这个类可以使你能访问多个程序集中的给定模块。
Type类也是用的比较多,我们可以通过Type类得到一个类的内部信息或者反射创建一个对象。一般有三种方式去得到Type对象。
Type type=typeof(类名);
Type type=ExampleClass.GetType();
Type type=Type.GetType("要获取的类型的程序集限定名称");
我们还注意到Assembly加载程序集时有3个方法,分别是Load(),LoadFrom(),LoadFile()。这三个方法将目标托管程序集加载到当前应用程序域然后生成对应程序集实例。我们要知道Load是优先使用的,因为LoadFrom其实是将信息传给Load去实现,LoadFile则不会加载程序集引用的程序集。我在百度查资料时还发现使用LoadFrom可能还会出错,LoadFrom不能加载标识相同但路径不同的程序集,当使用LoadFrom时,和Load方法一样第一次加载程序集的信息无论失败还是成功都会被缓存,那么加载目录A中的程序集C.dll时则会保存记录,如果加载B目录下的C.dll时则会直接给出第一次缓存的程序集,也就是目录A中的C.dll。
3.通过反射实现工厂模式
class Program
{
static void Main(string[] args)
{
//使用ReflectFactory工厂去得到想要的类
IPeople xiaoHua = ReflectFactory.CreatePeopleByReflect("XiaoHua");
IPeople xiaoHon = ReflectFactory.CreatePeopleByReflect("XiaoHon");
xiaoHua.Eat();
xiaoHon.Eat();
Console.ReadLine();
}
}
//通过这个类得到要创建的类
public class ReflectFactory
{
public static IPeople CreatePeopleByReflect(string typeName)
{
Type type = Type.GetType("ConsoleApplication1."+typeName);
ConstructorInfo ci = type.GetConstructor(System.Type.EmptyTypes);
return (IPeople)ci.Invoke(null);
}
} //定义了XiaoHua和XiaoHon2个类和它们的父接口IPeople
public interface IPeople
{
void Eat();
}
public class XiaoHua : IPeople
{
public void Eat()
{
Console.WriteLine("小花吃2个梨子");
}
}
public class XiaoHon : IPeople
{
public void Eat()
{
Console.WriteLine("小红吃3个苹果");
}
} //下面是不用反射的写法。这样的话就要为每个类写一个创造类或创造的方法,比如要得到XiaoHua类我们要再写一个GetXiaoHua类,
//如果又有新成员加入,那岂不是还要再新增类或方法,而采用反射则可以随便添加,只需要实现IPeople接口即可,这就是我体会到的反射的好处。
public interface FactoryPeople
{
IPeople GetPeople();
}
public class GetXiaoHua : FactoryPeople
{
public IPeople GetPeople()
{
return new XiaoHua();
}
}
public class GetXiaoHon : FactoryPeople
{
public IPeople GetPeople()
{
return new XiaoHon();
}
}
C#基础之反射的更多相关文章
- 黑马程序员:Java基础总结----反射
黑马程序员:Java基础总结 反射 ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 反射 反射的基石:Class类 Class类代表Java类,它的各个实例对象又分别 ...
- Go语言基础之反射
Go语言基础之反射 本文介绍了Go语言反射的意义和基本使用. 变量的内在机制 Go语言中的变量是分为两部分的: 类型信息:预先定义好的元信息. 值信息:程序运行过程中可动态变化的. 反射介绍 反射是指 ...
- Python 基础 三 反射
Python 基础 三 反射 今天我们先介绍一下反射这个概念,啥是反射?反射就是自己检测自己.在我们Python的面向对象中的反射是啥意思呢?就是通过字符串的形式操作对象相关的属性.python中的一 ...
- JAVA基础知识|反射
一.理解反射 1.1.基础概念 反射:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为ja ...
- GO学习-(17) Go语言基础之反射
Go语言基础之反射 本文介绍了Go语言反射的意义和基本使用. 变量的内在机制 Go语言中的变量是分为两部分的: 类型信息:预先定义好的元信息. 值信息:程序运行过程中可动态变化的. 反射介绍 反射是指 ...
- JAVA安全基础之反射
JAVA安全基础之反射 在JAVA安全中,反射是一个经常使用的技术,所以熟悉使用反射是非常必要的.下面就简单的讲下JAVA的反射的用法 什么是反射 每个类都有对应的Class类对象,该Class类对象 ...
- 黑马程序员_Java基础:反射机制(Reflection)总结
------- android培训.java培训.期待与您交流! ---------- 反射在java中有非常重大的意义,它是一种动态的相关机制,可以于运行时加载.探知.使用编译期间完全未知的clas ...
- C#基础|初探反射
什么是反射 我们编写的C#代码都可以编译成exe文件或dll文件.暂时先把他们叫做程序集吧,程序集中包含了很多信息.你写了一个类,类中会有字段,有属性,有方法,编译是会把这些信息保存在程序集中,暂时把 ...
- Java基础之一反射
反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)) 一.反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够 ...
- python基础(14)-反射&类的内置函数
反射 几个反射相关的函数可参考python基础(10)-匿名函数&内置函数中2.2.4反射相关 类的一些内置函数 __str__()&__repr__() 重写__str__()函数类 ...
随机推荐
- JavaScript(核心、BOM、DOM)
http://www.flyne.org/article/407 JavaScript(核心.BOM.DOM) JavaScript是基于对象和事件驱动的客户端脚本语言.有如下特点: 交互性 安全性( ...
- 协议森林08 不放弃 (TCP协议与流通信)
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! TCP(Transportation Control Protocol)协议与IP ...
- P1081 开车旅行
题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的 城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为 Hi,城市 ...
- 查找系统中jdk的位置
查找系统中jdk的位置: [root@localhost native]# find /|grep jni_md.h /var/lib/docker/overlay2/ec7a5439382a8a6d ...
- HDU 1158(非常好的锻炼DP思维的题目,非常经典)
题目链接: acm.hdu.edu.cn/showproblem.php?pid=1158 Employment Planning Time Limit: 2000/1000 MS (Java/Oth ...
- FLV封装格式分析
FLV官方文档:https://github.com/jiayayao/DataSheet/tree/master/media%20format/flv 一.FLV格式 FLV包括文件头(FLV he ...
- Android小游戏应用---撕破美女衣服游戏
ImageView after; ImageView before; @Override protected void onCreate(Bundle savedInstanceState) { su ...
- Cache Buffer 区别
Cache 一般位于CPU中, 分为 L1 Cache, L2 Cache, 是一种读的操作,把CPU刚用过的/循环使用的数据存储起来,当CPU再次使用时,可以直接从Cache存储器中调用,减少了等待 ...
- Ubuntu16.04测网速
wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0b4.tar.xz tar -xvJf Python-3.7.0b4.tar.xz c ...
- 使用DBNEWID Utility 修改oracle数据库的 db name 和 dbid
使用DBNEWID Utility 工具可以同时修改数据库名.DBID,也可以只修改其中一项 官方参考: https://docs.oracle.com/cd/E11882_01/server.112 ...