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__()函数类 ...
随机推荐
- TensorFlow函数(二)tf.get_variable() 和 tf.Variable()
tf.Variable(<initial - value>,name=<optional - name>) 此函数用于定义图变量.生成一个初始值为initial - value ...
- HTML5本地存储(Local Storage) 的前世今生
长久以来本地存储能力一直是桌面应用区别于Web应用的一个主要优势.对于桌面应用(或者原生应用),操作系统一般都提供了一个抽象层用来帮助应用程序保存其本地数据 例如(用户配置信息或者运行时状态等). 常 ...
- Kali-linux Gerix Wifi Cracker破解无线网络
Gerix Wifi Cracker是另一个aircrack图形用户界面的无线网络破解工具.本节将介绍使用该工具破解无线网络及创建假的接入点. 9.3.1 Gerix破解WEP加密的无线网络 在前面介 ...
- Css3 实现丝带效果
代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- LeetCode刷题(数据库)---- 超过5名学生的课
题:请列出所有超过或等于5名学生的课. 有一个courses 表 ,有: student (学生) 和 class (课程). 例如,表: +---------+------------+ | stu ...
- window resize和scroll事件的基本优化
转自 http://www.kankanews.com/ICkengine/archives/6564.shtml
- 映射Xml文件中的数据到JavaBean中
使用Java原生的javax.xml.bind包下的JAXBContext将一个Xml文件中的数据映射到一个JavaBean中 import java.io.File; import java.io. ...
- 决策树 - 可能是CART公式最严谨的介绍
目录 决策树算法 ID3算法[1] C4.5 改进[1] "纯度"度量指标:信息增益率 离散化处理 CART(分类与回归树,二叉) 度量指标 二值化处理 不完整数据处理 CART生 ...
- OO 第五、六、七次作业总结
第五次作业 算法与实现 这次的电梯因为要使用系统时间进行模拟,所以又是推倒了之前的重写的.最后采用三个电梯线程,一个调度线程,一个输入线程的方式. 源码分析图示 类图 方法分析 类分析 由上图看,由于 ...
- eclipse的git插件安装、配置与使用
Git是一个分布式的版本控制工具,本篇文章从介绍Git开始,重点在于介绍Git的基本命令和使用技巧,让你尝试使用Git的同时,体验到原来一个版 本控制工具可以对开发产生如此之多的影响,文章分为两部分, ...