C#反射的应用小结

1.何谓反射?

反射就是在运行的时候发现对象的相关信息.根据这些信息可以动态的执行对象的方法以及获取对象的属性所存储的值.使用.NET编写的代码时自动反射的,或者说是自我描述的.之所以可以反射,是通过编译后产生的元数据来做到的.因此,你可以在你的程序中使用反射来查找托管代码中的类型(包括类的名称,方法和参数)和与其相关的信息这其中包括执行被发现的代码.你也可以在程序运行的时候使用反射来创建,编译和运行代码.

2.反射的实例化

public static Assembly Load(string);

public static Assembly LoadFrom(string);

案例:

先定义一个类,方便以后使用:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Reflection;

using System.Text;

using System.Threading.Tasks;

namespace reflecting

{

class Program

{

static void Main(string[] args)

{

Assembly ass = Assembly.Load("reflecting");

Type t = ass.GetType("reflecting.NewClassw");

object o = Activator.CreateInstance(t, "grayworm", "http://hi.baidu.com/grayworm");

MethodInfo mi = t.GetMethod("show");

mi.Invoke(o, null);

Console.ReadKey();

}

}

public class NewClassw

{

public NewClassw(string name, string sex)

{ }

public NewClassw()

{ }

public void show()

{

Console.WriteLine("hello,syx");

}

}

}

第一部分:找到特定的成员

列出程序集中类的名称:

Assembly myAssembly = Assembly.Load("Basics");
Type[] types = myAssembly.GetTypes();
foreach(Type type in types)
{
  if(type.IsClass)
     Console.WriteLine(type.Name);
}

直接访问某个类(假如访问的是SomeClass类中带一个参数的方法)

MethodInfo mi = typeof(SomeClass).GetMethod("SomeMethod");

过滤某些特定的成员

System.Type类也提供了一些方法,用于把包含在一个类里或者其它的类型里的特定的类型过滤到一个集合中。如GetConstructors方法,GetMethods方法,GetProperties方法和GetEvents方法均允许你以数组的方式返回所有给定的类型或者通过使用过滤条件只返回特定的类型集合。
以下是过滤出是公用和静态的方法:

MethodInfo[] mis = typeof(OtherClass).GetMethods(BindingFlags.Public | BindingFlags.Static);

注释:如果想得到私有成员,则用BindingFlags.NonPublic,但你需要有相应的权限.

搜索某些特定的成员

FieldInfo fi;

AnotherClass ac = new AnotherClass();

MemberInfo[] memInfo = ac.GetType().FindMembers(MemberTypes.Field, BindingFlags.NonPublic | BindingFlags.Instance, null, null);

foreach (MemberInfo m in memInfo)

{

fi = m as FieldInfo;

if (fi != null)

{

Console.WriteLine("{0} of value:{1}", fi.Name, fi.GetValue(ac));

}

}

自定义搜索

这个程序定义了一个委托(与委托MemberFilter具有相同签名的方法)MySearchDelegate,用于定制搜索条件。创建了一个类filterObject,其包含两个字段,辅助我们自定义搜索条件。程序中调用了FindMembers,指出我们需要所有的属性类型。当一个属性类型被发现时,程序将激发MySearchDelegate并且传给它一个filterCriteria实例对象,这个委托将判断成员的名称是否满足自定义的搜索条件来返回True还是False。

using System;

using System.Reflection;

namespace Basics2

{

/**/

/// <summary>

/// 被反射的类

/// </summary>

public class SomeClass

{

private int m_id;

public int ID

{

get { return this.m_id; }

set { this.m_id = value; }

}

private string m_name;

public string Name

{

get { return this.m_name; }

set { this.m_name = value; }

}

private int m_type;

public int Type

{

get { return this.m_type; }

set { this.m_type = value; }

}

}

/**/

/// <summary>

/// 自定义的过滤对象类

/// </summary>

public class filterObject

{

public string criterion1 = "Name";

public string criterion2 = "ID";

}

public class Basics

{

/**/

/// <summary>

/// 自定义的搜索条件,回调的方法

/// </summary>

/// <param name="memberInfo"></param>

/// <param name="filterCriteria"></param>

/// <returns></returns>

public static bool MySearchDelegate(MemberInfo memberInfo, object filterCriteria)

{

if (memberInfo.Name == ((filterObject)filterCriteria).criterion1 || memberInfo.Name == ((filterObject)filterCriteria).criterion2)

return true;

return false;

}

public static void Main()

{

PropertyInfo pi;

//绑定自定义的搜索条件

MemberFilter mf = new MemberFilter(MySearchDelegate);

SomeClass sc = new SomeClass();

//使用FindMembers返回指定的属性

MemberInfo[] memInfo = sc.GetType().FindMembers(MemberTypes.Property, BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, mf, new filterObject());

foreach (MemberInfo m in memInfo)

{

pi = m as PropertyInfo;

Console.WriteLine(pi.Name);

}

Console.ReadLine();

}

}

}

第二部分  执行发现的代码

执行发现的代码的过程基本上要遵循以下几个基本的步骤:

1.加载程序集

2.找到你希望使用的类型或者类

3.创建该类型(或者类)的一个实例

4.找到你希望执行的该类型的某个方法

5.得到该方法的参数

6.调用该对象的方法并且传递给它恰当的参数.

创建发现的代码的实例

一旦找到你要找的类型,就可以使用System.Activator创建此类型的一个实例.你将会使用Avtivator类的方法CreateInstance众多版本中的一个.CreateInstance允许你指定你想要创建的对象,并且可选择的参数会应用到该对象的构造器上.

(1)在这里该对象的默认的构造器不用床底参数:

//SomeClass为一个类

object obj = System.Activator.CreateInstance(typeof(SomeClass));

(2)假设你想要创建一个特定对象的实例,其构造器是需要传递参数的.为此你需要把这些阐述的值作为一个数字的形式传递给CreateInstance.每一个参数的值需要对应该参数的类型,并且数组中参数的值需要与构造器的签名的顺序一致.

Type[] ts = {typeof(Int32)};
ConstructorInfo ci = typeof(SomeClass).GetConstructor(ts);
ParameterInfo[] pi = ci.GetParameters();
//创建一个数组,与返回的长度一样
object[] param = new object[pi.Length];
//给数组每个参数赋值
foreach(ParameterInfo p in pi)
{
  if(p.ParameterType == typeof(Int32))
    param[p.Position] = 100; //赋值
}
//最后可以创建实例化了
object o = System.Activator.CreateInstance(typeof(SomeClass),param);

到此,你已经得到了你的对象(SomeClass)的一个实例.接下来,让我们了解一下,如何调用该对象的方法.在之前,我们查询构造器的参数并把参数的值传给构造器,对于方法而言,这个处理过程是一样的.假设SomeClass类有一个SomeMethod方法,你想调用这个方法.为了保证粒子足够简单,建设方法SomeMethod没有任何参数(参数的处理过程同上.)为了能够用SomeMethod,你需要获取关于该方法的MethodInfo对象的一个引用.在这里你可以使用GetMethod或者GetMethods方法在你的类型上搜索.让我们使用GetMethod,并给其传递方法的名称.

MethodInfo mi=typeof(SomeClass).GetMethod(“SomeMethod”);

你不仅游泳了SomeClass的一个实例,而且也拥有了你希望调用该对象方法的引用mi,因此你可以使用MethodInfo.invoke调用你的目标方法了,你需要传递包含该方法的对象的会理和该方法需要的一组参数的值.如下:

mi.Invoke(o,null);

现在已经成功的创建了某个对象的一个实例,找到了该对象的某个方法,并且成功的调用了,而这些在涉及之初没有必要要知道该对象.

可以很容易的沿着这个例子向外延伸,创建一个类似于测试工具的实用工具.

转载于:https://www.cnblogs.com/android-blogs/p/6639002.html

C#高级编程----反射的小结相关推荐

  1. ASP.NET MVC 4高级编程(第4版)

    <ASP.NET MVC 4高级编程(第4版)> 基本信息 作者: (美)Jon Galloway Phil Haack Brad Wilson K. Scott Allen 译者: 孙远 ...

  2. ASP.NET MVC5 高级编程 第3章 视图

    参考资料<ASP.NET MVC5 高级编程>第5版 第3章 视图 3.1 视图的作用 视图的职责是向用户提供界面. 不像基于文件的框架,ASP.NET Web Forms 和PHP ,视 ...

  3. java主类与源代码名称_Java高级编程基础:类文件结构解析,看穿Class代码背后的秘密...

    类文件结构 在说完了JVM内部结构后,接下来我们需要说一下另外一个非常重要的基础概念Class类结构. 我们既然知道了开发的Java源代码会首先被编译成字节码文件保存,JVM的类加载器会读取这些文件内 ...

  4. Python学习笔记:面向对象高级编程(完)

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  5. Python学习笔记:面向对象高级编程(中上)

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  6. Python学习笔记:面向对象高级编程(上)

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  7. Atitit. 高级软件工程师and 普通的区别 高级编程的门槛总结

    Atitit.  高级软件工程师and 普通的区别 高级编程的门槛总结 1. 完备的知识体系 2 2. 编程理论/原理的掌握 2 1.1. 掌握常用的概念(ORM,IOC,AOP,event driv ...

  8. C#高级编程9 第17章 使用VS2013-C#特性

    C#高级编程9 第17章 使用VS2013 编辑定位到 如果默认勾选了这项,请去掉勾选,因为勾选之后解决方案的目录会根据当前文件选中. 可以设置项目并行生成数 版本控制软件设置 所有文本编辑器行号显示 ...

  9. [阅读体会] UNIX环境高级编程

    文章目录 写在开始阅读前 (我会的知识点,在体会里是不提的,并不是书中没有,这里着重于记录我之前不会的,但读过书之后学会的.) 第一章 第二章 2.1 引言 2.2 UNIX标准化 2.2.1 ISO ...

  10. C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(中)

    译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(中)),不对的地方欢迎指出与交流. 章节出自<Professional C# ...

最新文章

  1. ImageView / Text 使用 android:state_pressed 没有效果的处理方法
  2. 容器必须设置宽度吗_UI设计必须要具备的前端知识
  3. LinkedList 模拟栈和队列
  4. C#基础_值类型引用类型(十一)
  5. html 语义化标签拾遗
  6. Unity2018.2中文更新日志速览版
  7. ASP.NET中插入Flash
  8. CentOS系统yum源使用报错:Error: Cannot retrieve repository metadata
  9. 330UF16V 10*7.7片式铝电解电容封装
  10. Python百钱百鸡问题
  11. Squid代理权限的设置
  12. ​极飞无人机IPO申请获受理!主打农业应用,西安电子科技大学校友创立,高瓴百度是股东...
  13. chemdraw怎么连接两个结构_怎样在ChemDraw中绘制不定结构
  14. 我的 C# 学习经验分享
  15. Python书法碑帖分割(分别以对于汉字命名)
  16. 微信小程序实现替换logo功能
  17. 开始学习python了鸭
  18. Python——函数(2)之常见函数
  19. flume-异常Closing file:log.xxxtmp failed. Will retry again in 180 seconds
  20. windows7环境下theano安装

热门文章

  1. ubuntu 14.04 server 安装virtualbox (虚拟机)deb
  2. Java 开发流程、运行原理、JVM 规范与实现
  3. Matter-JS constraint 约束
  4. LayaAir HttpRequest 网络访问
  5. 阶段5 3.微服务项目【学成在线】_day04 页面静态化_17-页面静态化-模板管理-GridFS研究-存文件...
  6. 阶段3 3.SpringMVC·_07.SSM整合案例_02.ssm整合之搭建环境
  7. 阶段3 1.Mybatis_03.自定义Mybatis框架_7.自定义Mybatis的编码-实现基于注解配置的查询所有...
  8. tomcat优化实例
  9. javaScript中的变量作用域的闭包处理
  10. [BZOJ 3052] [wc2013] 糖果公园 【树上莫队】