C#高级编程----反射的小结
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);
现在已经成功的创建了某个对象的一个实例,找到了该对象的某个方法,并且成功的调用了,而这些在涉及之初没有必要要知道该对象.
可以很容易的沿着这个例子向外延伸,创建一个类似于测试工具的实用工具.
C#高级编程----反射的小结的更多相关文章
- C#高级编程 反射 代码示例
反射 反射(Reflection)是.NET中的重要机制,通过反射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等. 还可以获得每 ...
- WebGL高级编程:开发Web3D图形 PDF(中文版带书签)
WebGL高级编程:开发Web3D图形 目录 WebGL简介11.1 WebGL基础11.2 浏览器3D图形吸引人的原因21.3 设计一个图形API31.3.1 即时模式API31.3.2 保留模式A ...
- Atitit. 高级软件工程师and 普通的区别 高级编程的门槛总结
Atitit. 高级软件工程师and 普通的区别 高级编程的门槛总结 1. 完备的知识体系 2 2. 编程理论/原理的掌握 2 1.1. 掌握常用的概念(ORM,IOC,AOP,event driv ...
- ASP.NET MVC5 高级编程 第3章 视图
参考资料<ASP.NET MVC5 高级编程>第5版 第3章 视图 3.1 视图的作用 视图的职责是向用户提供界面. 不像基于文件的框架,ASP.NET Web Forms 和PHP ,视 ...
- ASP.NET MVC 4高级编程(第4版)
<ASP.NET MVC 4高级编程(第4版)> 基本信息 作者: (美)Jon Galloway Phil Haack Brad Wilson K. Scott All ...
- 《Hadoop》对于高级编程Hadoop实现构建企业级安全解决方案
本章小结 ● 理解企业级应用的安全顾虑 ● 理解Hadoop尚未为企业级应用提供的安全机制 ● 考察用于构建企业级安全解决方式的方法 第10章讨论了Hadoop安全性以及Hadoop ...
- 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# ...
随机推荐
- Java发送邮件时标题和发件人乱码
最近碰到一个问题,Java发送邮件时,查看邮箱结果,发件人及邮件标题正文全部乱码 通过翻阅资料,原因及解决方法如下: // Set Subject: 头字段 message.setSubject(Mi ...
- 通过使用CSS字体阴影效果解决hover图片时显示文字看不清的问题
1.前言 最近需要加入一个小功能,在鼠标越过图片时,提示其大小和分辨率,而不想用增加属性title来提醒,不够好看.然而发现如果文字是一种颜色,然后总有概率碰到那张图上浮一层的文字会看不到,所以加入文 ...
- Day4--------------对文件的权限管理
一.文件权限 ls -l 显示当前文件详细信息 例: -rw-r--rwx.1 root root 1415 11月 9 20:21 anaconda-ks.cfg 依次顺序为:权限信 ...
- OCM_第七天课程:Section3 —》数据库可用性
注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...
- php中静态方法和静态属性的介绍
静态分为两个部分:静态属性和静态方法 静态的东西都是给类用的(包括类常量),非静态的都是给对象用的 静态属性 在定义属性的时候,使用关键字static修饰的属性称之为静态属性. 静态方法 使用stat ...
- (八)CXF添加自定义拦截器
前面我们说到CXF添加内置的拦截器,今天的话,我们来讲下如何添加自定义拦截器: 我们的实例是客户端访问服务端webservice接口要加权限认证. 我们思路先说下.我们可以通过在SOAP消息的Head ...
- python 全栈开发,Day122(人工智能初识,百度AI)
一.人工智能初识 什么是智能? 我们通常把人成为智慧生物,那么”智慧生物的能力”就是所谓的”智能”我们有什么能力?听,说,看,理解,思考,情感等等 什么是人工智能? 顾名思义就是由人创造的”智慧能力” ...
- python 全栈开发,Day110(django ModelForm,客户管理之 编辑权限(一))
昨日内容回顾 1. 简述权限管理的实现原理. 粒度控制到按钮级别的权限控制 - 用户登陆成功之后,将权限和菜单信息放入session - 每次请求时,在中间件中做权限校验 - inclusion_ta ...
- 获取更新元素文本html()
html() 方法,获取元素文本,包含元素标签,也可以设置元素的文本值(包含元素标签),还可以包含子元素标签.相当于JavaScript中的innerHTML. <!DOCTYPE html&g ...
- IntelliJ IDEA设置不自动打开最后关闭的项目