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__()函数类 ...
随机推荐
- IOS XMPP总结
//前言:仿weixin实现一个即时通讯的案例,支持版本7.0以上 "准备工作 创建项目时使用git" /* 显示隐藏文件,看到git的文件夹 defaults write com ...
- Angular2 Router路由相关
路由设置 Angular中路由的配置应该按照先具体路由到通用路由的设置,因为Angular使用先匹配者优先的原则. 示例: 路由设置如下: export const reportRoute: Rout ...
- python网络爬虫--简单爬取糗事百科
刚开始学习python爬虫,写了一个简单python程序爬取糗事百科. 具体步骤是这样的:首先查看糗事百科的url:http://www.qiushibaike.com/8hr/page/2/?s=4 ...
- Codeforces Round #443 (Div. 2) 【A、B、C、D】
Codeforces Round #443 (Div. 2) codeforces 879 A. Borya's Diagnosis[水题] #include<cstdio> #inclu ...
- Django的时区设置问题
1.Django的时区问题 django默认的时区是UTC,平时是没有什么影响的,但是在需要将时间戳转换成本时区的时间或者是获取当前的本地的localtime的时候就出现了问题.之前程序在测试时是运行 ...
- web-ctf随机数安全
rand() 函数在产生随机数的时候没有调用 srand(),则产生的随机数是有规律可询的. 产生的随机数可以用下面这个公式预测 : state[i] = state[i-3] + state[i-3 ...
- jquery 中 attr 和 prop 的区别
问题:在jQuery引入prop方法后,什么时候使用attr,什么时候使用prop,两者区别. 判断: 对于HTML元素本身所有的固有属性,在处理的时候,使用prop方法 对于HTML元素后来我们自己 ...
- sqoop2启动job报错
set option --name verbose --value true #打开报错详情输出 Exception has occurred during processing command ...
- Python KafkaProducer and KafkaConsumer的开发模块
1.在python中往kakfa写数据和读取数据,使用的是python-kafka库 2.消费者需持续写入数据,因groupid存在偏移量,才能看看到数据. 3.安装库的命令为pip install ...
- 【题解】洛谷P1966 [NOIP2013TG] 火柴排队(树状数组+逆序对)
次元传送门:洛谷P1966 思路 显然在两排中 每排第i小的分别对应就可取得最小值(对此不给予证明懒) 所以我们只在意两排的火柴是第几根 高度只需要用来进行排序(先把两个序列改成有序的方便离散化) 因 ...