惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hacker News: Ask HN
Hacker News: Ask HN
H
Help Net Security
Microsoft Azure Blog
Microsoft Azure Blog
B
Blog RSS Feed
Jina AI
Jina AI
Stack Overflow Blog
Stack Overflow Blog
量子位
博客园_首页
Vercel News
Vercel News
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Forbes - Security
Forbes - Security
IT之家
IT之家
N
News and Events Feed by Topic
S
Security Affairs
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Webroot Blog
Webroot Blog
Recorded Future
Recorded Future
L
LangChain Blog
Y
Y Combinator Blog
AI
AI
MyScale Blog
MyScale Blog
大猫的无限游戏
大猫的无限游戏
小众软件
小众软件
Know Your Adversary
Know Your Adversary
AWS News Blog
AWS News Blog
Help Net Security
Help Net Security
Cyberwarzone
Cyberwarzone
L
Lohrmann on Cybersecurity
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Google Online Security Blog
Google Online Security Blog
V2EX - 技术
V2EX - 技术
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
PCI Perspectives
PCI Perspectives
I
Intezer
T
Tenable Blog
G
Google Developers Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
T
Troy Hunt's Blog
L
LINUX DO - 最新话题
云风的 BLOG
云风的 BLOG
C
CXSECURITY Database RSS Feed - CXSecurity.com
有赞技术团队
有赞技术团队
O
OpenAI News
P
Proofpoint News Feed
TaoSecurity Blog
TaoSecurity Blog
C
Check Point Blog
Last Week in AI
Last Week in AI
S
Schneier on Security
Simon Willison's Weblog
Simon Willison's Weblog
Blog — PlanetScale
Blog — PlanetScale

博客园 - 右手边

C#动态执行代码 这是一个广为流传的关于项目管理的通俗讲解 [史上最狂妄的演讲]你不服都不行<英汉版>~~ - 右手边 - 博客园 关于页面动态添加控件 利用反射动态创建对象 使用反射技术动态创建类对象(实例代码) 基于ASP.NET的Web动态控件创建 家中请客(最佳ERP教材)- - 2007年4月25日 经典的几句英文 网上英语免费杂志在钱订阅网址 将(Oracle)数据库表导出到Excel,并生成文件(C#实现) B/S结构与C/S结构 AJAX三步走 Ajax简单例子 Oracle 启动与关闭例程 AJAX的原理 VB资料库-无限下载 ASP.Net中程序构架与程序代码的分离 Oracle 系统结构
利用反射来动态创建实例和调用方法(上)
右手边 · 2007-05-25 · via 博客园 - 右手边

利用反射来动态创建实例和调用方法(上)

Posted on 2007-05-25 11:22  右手边  阅读(1523)  评论()    收藏  举报

利用反射来动态创建实例和调用方法(上)

2007-04-13 13:18

利用反射来动态创建实例和调用方法(转)
        .NET 的一个强大功能是它可以通过一种称为反射(reflection)的过程访问应用程序的元数据。简单地说,反射就是运行时查询类型信息的能力。.NET Reflection API 实际上是在System.Reflection命名空间中定义的一组类。这些类使你能够按逻辑方式查看配件和类型信息。我在这里并不对反射的基本原理做讲解,只是针对一些反射的基本用法做一下介绍。关于反射的定义还有一些理论上的东西请参见网上其它的文章或是msdn。
        这里我只讲三个方面的应用:一是用反射来创建实例,二是用反射调用实例的方法,三是用反射调用实例的属性。这三个是反射的最基本用法和用途,其它的用法比如调用实例的特性、委托等等,与这三个差不多,请读者自己学习。
        学习反射要具备很多基本知识,这里并不准备讲这些东西,只是开门见山的讲其三个用法。
        在此之前,我想说说Type这个类,不感兴趣的读者可以不看这一段。反射的核心是抽象的System.Type这个类。这个类是所有反射操作的根并且代表系统中的每个类型。这个类是访问元数据的主要方式,它作为通向Reflection API的通道。Type类的成员用于获取关于类型声明的信息。这些信息包括为类型定义的所有构造器、方法、字段、特性和事件,以及类所在的模块和配件。 Type对象可以代表以下任何类型:类、值类型、数组、接口、指针和枚举。
       
1.      使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其它特定的非全局方法。
2. 使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如public 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetConstructors或 GetConstructor方法来调用特定的构造函数。
3.使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如public 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetMethods或GetMethod方法来调用特定的方法。
4.使用FieldInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。
5.使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。
6.使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。
7.使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。

        上面的程序很简单,唯一要说的就是
MethodInfo mi = type.GetMethod( "FunctionWithParameter" ,                                              BindingFlags.Public        |BindingFlags.Instance , null , new                                                 Type[]{ typeof(string) } , null );
这个GetMethod中的参数说明了,如下:
public virtual MethodInfo GetMethod(
   string name,
   BindingFlags bindingAttr,
   Binder binder,
   Type[] types,
   ParameterModifier[] modifiers
);
参数
name
包含要获取的方法名称的 String。
bindingAttr
一个位屏蔽,由一个或多个指定搜索执行方式的 BindingFlags 组成。
binder
一个 Binder 对象,该对象定义一组属性并启用绑定,而绑定可能涉及选择重载方法、强制参数类型和通过反射调用成员。
types
表示此方法要获取的参数的个数、顺序和类型的 Type 对象数组。
获取不使用参数的方法的 Type 类型的空数组(即 Type[] types = new Type[0])。
modifiers
ParameterModifier 对象数组,表示与 types 数组中的相应元素关联的属性。默认的联编程序不处理此参数。
返回值
表示符合指定要求的方法的 MethodInfo 对象或是NULL;

其中bindingAttr中的BindingFlags定义如下。

成员名称
  
说明
  

CreateInstance
受 .NET Framework 精简版的支持。
  
指定“反射”应该创建指定类型的实例。调用与给定参数匹配的构造函数。忽略提供的成员名。如果未指定查找类型,将应用 (Instance |Public)。调用类型初始值设定项是不可能的。
  
512
DeclaredOnly
受 .NET Framework 精简版的支持。
  
指定只应考虑在所提供类型的层次结构级别上声明的成员。不考虑继承成员。
  
2
Default
受 .NET Framework 精简版的支持。
  
不指定绑定标志。
  
0
ExactBinding
受 .NET Framework 精简版的支持。
  
指定提供参数的类型必须与对应形参的类型完全匹配。如果调用方提供一个非空 Binder 对象,则“反射”将引发异常,因为这意味着调用方正在提供的 BindToXXX 实现将选取适当的方法。
“反射”建立通用类型系统的访问规则模型。例如,如果调用方在相同的程序集内,则它不需要内部成员的特殊权限。否则,调用方需要 ReflectionPermission。这与保护成员、私有成员等成员的查找是一致的。
一般原则是,ChangeType 应只执行永远不会丢失数据的扩展强制。扩展强制的一个例子是将 32 位有符号整数值强制为 64 位有符号整数值。这与窄缩强制不同,后者可能丢失数据。窄缩强制的一个例子是将 64 位有符号整数强制为 32 位有符号整数。
默认联编程序忽略此标志,而自定义联编程序可以实现此标志的语义。
  
65536
FlattenHierarchy
受 .NET Framework 精简版的支持。
  
指定应返回该层次结构以上的静态成员。静态成员包括字段、方法、事件和属性。不返回嵌套类型。
  
64
GetField
受 .NET Framework 精简版的支持。
  
指定应返回指定字段的值。
  
1024
GetProperty
受 .NET Framework 精简版的支持。
  
指定应返回指定属性的值。
  
4096
IgnoreCase
受 .NET Framework 精简版的支持。
  
指定当绑定时不应考虑成员名的大小写。
  
1
IgnoreReturn
受 .NET Framework 精简版的支持。
  
在 COM interop 中用于指定可以忽略成员的返回值。
  
16777216
Instance
受 .NET Framework 精简版的支持。
  
指定实例成员将包括在搜索中。
  
4
InvokeMethod
受 .NET Framework 精简版的支持。
  
指定要调用一个方法。这可能不是构造函数或类型初始值设定项。
  
256
NonPublic
受 .NET Framework 精简版的支持。
  
指定非公共成员将包括在搜索中。
  
32
OptionalParamBinding
受 .NET Framework 精简版的支持。
  
返回其参数计数与提供参数的数目匹配的成员集。此绑定标志用于所带参数具有默认值的方法和带变量参数 (varargs) 的方法。此标志应只与 Type.InvokeMember 一起使用。
具有默认值的参数仅用在省略尾部参数的调用中。它们必须是最后的参数。
  
262144
Public
受 .NET Framework 精简版的支持。
  
指定公共成员将包括在搜索中。
  
16
PutDispProperty
受 .NET Framework 精简版的支持。
  
指定应调用 COM 对象的 PROPPUT 成员。PROPPUT 指定使用值的属性设置函数。如果属性同时具有 PROPPUT 和 PROPPUTREF,而且需要区分调用哪一个,请使用 PutDispProperty。
  
16384
PutRefDispProperty
受 .NET Framework 精简版的支持。
  
指定应调用 COM 对象的 PROPPUTREF 成员。PROPPUTREF 指定使用引用而不是值的属性设置函数。如果属性同时具有 PROPPUT 和 PROPPUTREF,而且需要区分调用哪一个,请使用 PutRefDispProperty。
  
32768
SetField
受 .NET Framework 精简版的支持。
  
指定应设置指定字段的值。
  
2048
SetProperty
受 .NET Framework 精简版的支持。
  
指定应设置指定属性的值。对于 COM 属性,指定此绑定标志与指定 PutDispProperty 和 PutRefDispProperty 是等效的。
  
8192
Static
受 .NET Framework 精简版的支持。
  
指定静态成员将包括在搜索中。
  
8
SuppressChangeType
受 .NET Framework 精简版的支持。
  
未实现。
  
131072

        以上只是对反射作了一个简单的介绍,大家可以按照上面的程序照猫画虎,写出自己需要的反射程序。也许你会有疑问,不是说反射可以在程序运行时动态创建类型吗?上面的例子虽然也是动态创建的,可以还是要在知道类的名字和类中方法名的情况下才可以动态的调用类中的函数,怎样实现程序动态加载dll并且执行里面的函数呢?这还需要接口和抽象类的相关知识,请看我关于接口和抽象类的这篇文章。
如果你对接口和抽象类已经很清楚了,那么可以直接看下面这篇文章,
里面有具体怎么利用反射和接口来实现动态加载dll的例子。
(其实上面这两篇文章我已经写完了,但总是觉得有些地方写得很肤浅,有些地方写得不明不白,其实反射本身就是很灵活的东西,本人水平有限,所以决定暂时先不发布上面两篇,等我对反射的理解更深时再发布。)