动态装载和使用类型
Reflection提供诸如Microsoft Visual Basic.NET和JScript语言编译器使用的底层结构来实施隐性后绑定。绑定是定位与某一特定类型相对应的声明的过程。当这个过程发生在运行的时候,而不是编译的时候,它被称为后绑定。Visual Basic.NET使你可以在你的代码中使用隐性后绑定;VisualBasic.NET编译器调用helper 方法,使用Reflection获得对象类型。传递给helper 方法的参数 使适当的方法可以在运行时被调用。这些参数是调用方法(对象)的实例,被调用方法的名字(字符串),及传递给被调用方法的参数。(一个对象数组)。
在以下代码例子中, Visual Basic.NET编译器通过Reflection隐性地 来对一在编译时不知类型的对象调用方法。HelloWorld 类有一种 PrintHello 方法,可以打印出 "Hello World" 及传递给PrintHello 方法的一些文本。本例中PrintHello 方法 调用实际上是Type. InvokeMember ; Visual Basic 代码 允许PrintHello 方法被调用,仿佛 对象的类型 (helloObj)在编译时就已经知道了(前期绑定),而不是在运行时(后绑定)。
[Visual Basic]
Imports System
Module Hello
Sub Main()
' Set up variable.
Dim helloObj As Object
' Create the object.
helloObj = new HelloWorld()
' Invoke the print method as if it was early bound
' even though it's really late bound.
helloObj.PrintHello("Visual Basic Late Bound")
End Sub
End Module
自定义绑定
Reflection除了可以隐性地被编译器用于后绑定,也可以在代码中显示使用,来完成后绑定。
common language runtime 支持多种编程语言,这些语言的绑定规则互不相同。在前绑定的情况下,代码生成器能完全控制绑定。然而,在使用Reflection的后绑定中,绑定必须由自定义绑定控制。Binder类提供成员选择与调用的自定义控制。
使用自定义绑定, 您可以在运行时装载assembly,获得assembly中关于类型的信息,指明您索要的类型,并且调用方法,访问字段,或类型的属性。如果在编译时您不知道对象的类型,该技术就显得格外有用,比如,当对象类型依赖于用户输入时。以下例子中的代码显示了在HelloWorld.dll assembly 中,被动态使用Reflection调用的方法,第一个在Visual Basic.NET,第二个在C#中。
[Visual Basic]
' This class is deployed as an assembly consisting Hello World string.
Private m_helloWorld As String = "HelloWorld"
' Default public constructor.
Public Sub New()
End Sub 'New
' Print "Hello World" plus thepassed text.
Public Sub PrintHello(txt As String)
' Output to the Console.
Console.WriteLine((m_helloWorld & "" & txt))
End Sub
End Class
Imports System
Imports System.Reflection
Module VisualBasicLateHello
Sub Main()
' Set up the variables.
Dim assem as System.Reflection.Assembly
Dim obj as Object
Dim helloType as Type
Dim printMethod as MethodInfo
' Load the assembly to use.
assem = System.Reflection.Assembly.Load("HelloWorld")
' Get the type to use from the assembly.
helloType = assem.GetType("HelloWorld")
' Get the method to use from the type.
printMethod = helloType.GetMethod("PrintHello")
' Create an instance of the type.
obj = Activator.CreateInstance(helloType)
' Create an array to hold the arguments.
Dim args(1) as Object
' Set the arguments.
args(0) = "From Visual Basic Late Bound"
' Invoke the method.
printMethod.Invoke(obj, args)
End Sub
End Module
以下为C# 版:
[C#]
// This class is deployed as an assembly consisting of one DLL,
// called HelloWorld.dll.
using System;
public class HelloWorld {
// Constant Hello World string.
private const String m_helloWorld = "Hello World";
// Default public constructor.
public HelloWorld() {
}
// Print "Hello World" plus the passed text.
public void PrintHello(String txt) {
// Output to the Console.
Console.WriteLine(m_helloWorld + " " + txt);
}
}
// Illustrates reflection's late binding functionality.
// Calls the PrintHello method on a dynamically loaded
// and created instance of the HelloWorld class.
using System;
using System.Reflection;
public class CSharpLateHello {
public static void Main() {
// Load the assembly to use.
Assembly assem = Assembly.Load("HelloWorld");
// Get the type to use from the assembly.
Type helloType = assem.GetType("HelloWorld");
// Get the method to call from the type.
MethodInfo printMethod = helloType.GetMethod("PrintHello");
// Create an instance of the HelloWorld class.
Object obj = Activator.CreateInstance(helloType);
// Create the args array.
Object[] args = new Object[1];
// Set the arguments.
args[0] = "From CSharp Late Bound";
// Invoke the PrintHello method.
printMethod.Invoke(obj, args);
}
}
InvokeMember 与 CreateInstance
可以使用Type.InvokeMember来调用某类型成员。各种类的CreateInstance 方法,例如System.Activator 和 System.Reflection.Assembly,是InvokeMember的专用形式,用于生成某类型新的实例。Binder类在这些方法中,被用于重载解析和参数转换。
以下例子中的代码显示了三种可能的参数转换及成员选择的组合。在Case1中, 不需要参数转换或成员选择。在Case 2中,只需要成员选择。在Case3中, 只需要参数转换。
[C#]
public class CustomBinderDriver
{
public static void Main (string[] arguments)
{
Type t = typeof (CustomBinderDriver);
CustomBinder binder = new CustomBinder();
BindingFlags flags = BindingFlags.InvokeMethod|BindingFlags.Instance|
BindingFlags.Public|BindingFlags.Static;
//Case 1. Neither argument coercion nor memberselection is needed.
args = new Object[] {};
t.InvokeMember ("PrintBob", flags,binder, null, args);
//Case 2. Only member selection is needed.
args = new Object[] {42};
t.InvokeMember ("PrintValue", flags,binder, null, args);
//Case 3. Only argument coercion is needed.
args = new Object[] {"5.5"};
t.InvokeMember ("PrintNumber",flags, binder, null, args);
}
public static void PrintBob ()
{
Console.WriteLine ("PrintBob");
}
public static void PrintValue (long value)
{
Console.WriteLine ("PrintValue ({0})",value);
}
public static void PrintValue (String value)
{
Console.WriteLine ("PrintValue/"{0}/")",value);
}
public static void PrintNumber (double value)
{
Console.WriteLine ("PrintNumber ({0})",value);
}
}
当存在多于一个的同名成员时,就需要有重载解析。Binder.BindToMethod 和Binder.BindToField 方法可以用来绑定到一个成员。Binder.BindToMethod也可以通过get 和set 属性访问器提供属性解析。
BindToMethod 返回可被调用的MethodBase. 如无可用的调用则返回null. 如果无法调用,BindToMethod 返回 MethodBase 为 调用或 null。MethodBase返回值无需是match参数之一,尽管事实往往如此。
调用者 也许会想得到ByRef 参数的返回。所以,如果BindTo方法改动过参数数组,Binder 允许客户使参数数组映射回它原来的表格。为了实现这点,调用者必须确保参数顺序不变。当参数由名字传递,Binder重新整理参数组,以供调用者察看。
可用成员是指那些在类型或任何基本类型中定义的那些成员。如果指明BindingFlags.NonPublic,任何访问级别的成员都会在返回中。如果BindingFlags.NonPublic 没有被指明,binder必须执行访问规则。当指明Public或 NonPublic 绑定标志, 你必须也指明Instance 或Static 标志, 否则不会有成员返回。
如果只有一个成员与名字对应,就不需要回调,也就完成到这个方法的绑定。Case 1 中的代码例子表明了这一点:只有一个可用的PrintBob 方法, 所以,不需要回调。
如在可用集中,有多于一个成员。所有这些方法被传递给BindTo方法, 再由它选择适当的方法,并且返回。在 Case 2 中的代码例子中,有两种叫做PrintValue的方法。合适的方法取决于对BindToMethod调用。
ChangeType 执行参数转换, 它把实际参数转变为选定方法的参数类型。即使类型已经完美匹配,ChangeType也会针对每个参数被调用。
在 Case 3 中的代码例子中, 值为"5.5"的String类型的一个实际参数以正式参数Double类型被传递给方法。要想调用成功,字符串值"5.5"必须被转变为一个double值。ChangeType 执行了这种转变。
ChangeType 仅执行无损失转换, 如下表所示:
Source Type Target Type
Any type Its base type
Any type Interface it implements
Char UInt16, UInt32, Int32, UInt64, Int64, Single, Double
Byte Char, UInt16, Int16, UInt32, Int32, UInt64, Int64, Single, Double
SByte Int16, Int32, Int64, Single, Double
UInt16 UInt32, Int32, UInt64, Int64, Single, Double
Int16 Int32, Int64, Single, Double
UInt32 UInt64, Int64, Single, Double
Int32 Int64, Single, Double
UInt64 Single, Double
Int64 Single, Double
Single Double
Non-reference type Reference type
Type类有Get方法,可使用Binder类型的参数的来解析对某成员的引用。Type.GetConstructor,Type. GetMethod , 和 Type.GetProperty 通过提供某成员的签名信息来查找该成员。它们调用Binder.SelectMethod和Binder.SelectProperty 以选择适合方法的签名信息。
相关文章:

求1 + 2 + 3...+ n的和
题目:求1 2 3 ... n 的和 要求:不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C) 答: #include "stdafx.h" #include <iostream>using namespace std;//1、函数查找表法 typedef in…

Debussy的安装
下载完成后对软件安装包进行解压缩,得到安装文件和破解文件。 双击Debussy-54v9-NT.exe进行安装,出现以下界面,选择安装的路径。 选择安装类型,最好选择typical类型。 选择相关配置。 进行安装。 选择Yes继续,dont dis…

如何调试你的C#程序
作者:龙山文化 文章来源:ASPCool.com欢迎来到C#的奇妙天空,在这里,希望你能获得你想获得的东西,.我们真诚希望能给你带来巨大的帮助,带你进入另外一个广阔的空间。 Come on. Follow me and then U can W…

SSAS使用时间智能解决本年累计、同比、环比【转载】
通常,我们需要使用MDX来定义本年累计、同比、环比等一系列基于时间维度的计算指标。但是这样有一个麻烦的地方就是比如我有50个基础指标,每个指标都需要本年累计,那我就需要写50遍下面的语句:create member CURRENTCUBE.[MEASURES…
良心贴!没想到 Google 排名第一的编程语言,可以这么简单!
作为最近几年最火的编程语言,Python(没有之一)已经走过了20多个年头。也难怪,作为大数据时代和人工智能时代的必备语言,Python 的优点太多了,语言简洁、易学、开发效率高、可移植性强......不过它火起来的主…

报错 org.springframework.beans.factory.BeanCreationException
2019独角兽企业重金招聘Python工程师标准>>> 一.问题背景: spring mvc eclipse启动报错:org.springframework.beans.factory.BeanCreationException 二.分析 1.写了一个名为“User”的 实体bean,然后写了有参构造函数,…
醉没醉,带上智能手机走两步就知道
来源 | HyperAI超神经场景描述:斯坦福大学和匹兹堡大学的研究小组,最近发表了一项用智能手机检测醉酒状态的研究,可利用步态特征检测相应的血液和呼吸酒精浓度。以后喝没喝多,用你的手机测一测就知道。关键词:智能手机…

Linux编程常见问题
错误提示:Makefile:2: *** 遗漏分隔符 。 停止。原因makefile中 gcc语句前 缺少一个 tab分割符错误提示: bash: ./makefile: 权限不够原因 makefile 是文本文件不可执行,即使是root,也会权限不够我们应该在命令行下使用make&#…

网络工程师转售前的条件
昨天出差回来的时候已是凌晨四点,辛勤工作的早餐已经开始忙碌了。你走之后的第一周,房子空荡荡的,就剩下你的头发和发髻,还有你留下的信。真的很对不起你,从参加工作开始,我们总是聚少离多,很多…

python流程控制:while循环
python编程中whihe语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务。 while循环语句格式: while <判断条件>:执行语句 count 0 while (count <9):print("The count …
阿里动物园再添新丁,小蛮驴搞定物流最后三公里
作者 | 硬核云顶宫责编 | 李雪敬头图 | CSDN 下载自视觉中国今天的云栖大会上,阿里动物园再添新丁,不再这个新加入的动物既不是骡子也不是马,而是小蛮驴,这是一个专门解决物流最后三公里的AI机器人。今天的云栖大会,阿…

C语言中的CONST使用
C中的CONST使用 const是一个C语言的关键字,它限定一个变量不允许被改变。使用const在一定程度上可以提高程序的安全性和可靠性。 const的使用是c语言中一个比较微妙的地方,请看下面几个问题。 问题:const变量 和 常量 为什么下面的例子在…

一个项目可以有多个源代码路径
这样我们就建立了一个新的代码路径~~

x-http-wrapper: 如何解决每次发版时,修改http相关代码造成的错误!(Android、iOS、h5)...
其实是我做了个开源工具(^__^),拿出来给大家鉴赏下,欢迎大家提意见项目:github.com/xuyt11/x-ht… 欢迎关注和star 。功能:这是一个http相关代码的创建工具。 现在我们每一次发版,基本上都会涉及到http相关的修改&…
设计一款编程语言有多难?
作者 | DAVID CASSEL译者 | 弯月,责编 | 郑丽媛题图 | 自视觉中国来源 | CSDN(ID:CSDNnews)最近,Ruby编程语言的创始人兼主设计师、云平台即服务公司Heroku的Ruby首席架构师松本行弘在一次演讲中表示,由松本…

在 DW 中插入 Flash 的参数详解
作者:macromedia 文章来源: 蓝色理想 在Dreamweaver中插入FLASH后还可以有很多的控制参数,点属性面板右下的参数钮,就会有参数和值的加入。大家可以自由的控制, 以下内容摘自 Flash MX 2004 帮助文档 参数和属性下…

C语言中文件的读写(fputc和fgetc)(putchar和getchar)
文件打开之后就可以对文件进行读写了。 1、fputc(ch,fp); 将字符ch输出到(即写到)fp所指向的文件中。如果输出成功,返回字符ch的值,否则返回EOF(-1) putchar(c) 是从fputc中派生出来的,在stdio.…

转 微博 linux中ctime,mtime,atime的区别
http://blog.sina.com.cn/s/blog_67178440010101gr.html 当你同熟练的UNIX用户进行交谈时,你经常会听到他们傲慢地讲出术语“改变时间(change time)”和“修改时间(modification time)”。对于许多人(和许多字典而言),改变和修改是相同的。这里会有什么不同那&#…

WEB 打印的相关技术分析
文/谢康 做Web开发的人员一定都会面临一个共同的难题,那就是打印。的确,相对于Windows桌面应用程序来讲,Web应用程序的打印有种种限制,技术人员在项目开发过程中经常会遇到用户这样或那样的需求. 做过桌面应用开发的人都会非常熟悉…

jquery validate使用
一、用前必备 官方网站:http://bassistance.de/jquery-plugins/jquery-plugin-validation/ API: http://jquery.bassistance.de/api-browser/plugins.html 当前版本:1.5.5 需要JQuery版本:1.2.6, 兼容 1.3.2 <script src"../js/jquer…
Python程序员的“避坑”指南
结合我最近这些年的Python学习、开发经验,发现90%的人在学Python时都会遇到下面这些问题:1. 没什么经验根本不知道从何学起,而且应用方向太多了根本不知道该选择什么方向...2. 基础入门看似简单,但是进阶实战就举步维艰࿰…

java web项目流程小结
java web项目从发出请求到返回结果流程整理:客户发出请求,通过web.xml 中配置的DispatchServlet接收请求并调用 handlerMapping 将请求分发到对应的Controller,Controller调service,service调dao,dao层根据方法名对应到sql.xml,通…

snmp在企业网中的应用
一.snmp简介 snmp概念 SNMP(Simple Network Management Protocol,简单网络管理协议)的前身是简单网关监控协议(SGMP),用来对通信线路进行管理。随后,人们对SGMP进行了很大的修改,特别是加入了符合Internet定义的SMI和MIB:体系结构…

浅谈在ASP.NET中数据有效性校验的方法
作者:未知作为一名程序员,一定要对自己编写的程序的健壮性负责,因此数据的校验无论在商业逻辑还是系统实现都是必不可少的部分。我这里总结了一种自认为比较不错的asp.net(C#)的数据校验方法,如大家探讨。主…
关于Python 3.9,那些你不知道的事
作者 | Ayushi Rawat编译 | 高卫华题图 | 视觉中国Python一直在满足社区需求,并且将成为未来使用最多的语言。Python的下一个版本带来了更快速的进程释放,性能的提升,简便的新字符串函数,字典并集运算符以及更兼容稳定的内部API。…

memcache缓存失效
缓存过期 memcached在处理过期的缓存项时,采用懒惰模式处理方法。 缓存项过期,不会立即删除,直到对该缓存项执行了get操作,才会删除过期缓存。> set key 0 10 > test > stats //查看curr_items的值 > get key //超过过…

ASP.NET HTTP 运行时
ASP.NET HTTP 运行时一个请求从 URL 字符串到 HTML 代码的“漫长曲折”之路 Dino EspositoWintellect 2003年7月10日 摘要:本文详细介绍了 HTTP 运行时的组成部分,以及在处理对 ASP.NET 应用程序的各种请求时采用的逻辑。文章还以 Web Garden 模型和最新…

C++中的const关键字(zz)
【补充】mutable关键字有时我们希望类的数据成员即使在const成员函数中,依然是可以修改的,这时就可以把它们声明为mutable来实现。这样的应用,比如记录各种操作的调用次数,这时,即使在const中,依然要修改计…
Python让你成为AI 绘画大师,简直太惊艳了!(附代码))
作者 | 李秋键责编 | 李雪敬头图 | CSDN下载自视觉中国引言:基于前段时间我在CSDN上创作的文章“CylcleGAN人脸转卡通图”的不足,今天给大家分享一个更加完美的绘制卡通的项目“Learning to Cartoonize Using White-box Cartoon Representations”。首先…
Vue 2 | Part 4 v-bind绑定元素属性和样式
这期跟大家分享的,是v-bind指令。它可以往元素的属性中绑定数据,也可以动态地根据数据为元素绑定不同的样式。 绑定属性 最简单的例子,我们有一张图片,需要定义图片的src。我们可以直接在元素的属性里面定义: <div …