- 浏览: 3052792 次
- 性别:
- 来自: 海外
文章分类
- 全部博客 (430)
- Programming Languages (23)
- Compiler (20)
- Virtual Machine (57)
- Garbage Collection (4)
- HotSpot VM (26)
- Mono (2)
- SSCLI Rotor (1)
- Harmony (0)
- DLR (19)
- Ruby (28)
- C# (38)
- F# (3)
- Haskell (0)
- Scheme (1)
- Regular Expression (5)
- Python (4)
- ECMAScript (2)
- JavaScript (18)
- ActionScript (7)
- Squirrel (2)
- C (6)
- C++ (10)
- D (2)
- .NET (13)
- Java (86)
- Scala (1)
- Groovy (3)
- Optimization (6)
- Data Structure and Algorithm (3)
- Books (4)
- WPF (1)
- Game Engines (7)
- 吉里吉里 (12)
- UML (1)
- Reverse Engineering (11)
- NSIS (4)
- Utilities (3)
- Design Patterns (1)
- Visual Studio (9)
- Windows 7 (3)
- x86 Assembler (1)
- Android (2)
- School Assignment / Test (6)
- Anti-virus (1)
- REST (1)
- Profiling (1)
- misc (39)
- NetOA (12)
- rant (6)
- anime (5)
- Links (12)
- CLR (7)
- GC (1)
- OpenJDK (2)
- JVM (4)
- KVM (0)
- Rhino (1)
- LINQ (2)
- JScript (0)
- Nashorn (0)
- Dalvik (1)
- DTrace (0)
- LLVM (0)
- MSIL (0)
最新评论
-
mldxs:
虽然很多还是看不懂,写的很好!
虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩 -
HanyuKing:
Java的多维数组 -
funnyone:
Java 8的default method与method resolution -
ljs_nogard:
Xamarin workbook - .Net Core 中不 ...
LINQ的恶搞…… -
txm119161336:
allocatestlye1 顺序为 // Fields o ...
最近做的两次Java/JVM分享的概要
如果你试用(没错字,我就是说“试用”而不是“使用”)过System.Reflection.Emit的功能,可能会觉得这帖标题很怪——Builder系列跟对应的Info系列不是同根生么,前者继承对应的后者:
(最后一个不是Info系列的,所以用灰色表示了。前面的Assembly、Module和Type都算在“广义的Info系列”里)
那么通过SRE创建出一个类型之后,手上的Builder系列类型可以直接用于反射吗?
答案是:不行,Builder系列唯一的使命就是Emit,没有别的用途。
看个例子就明白:demo.cs
稍微解释一下这段代码:
开头的部分都是很常见的SRE boilerplate,先得到AssemblyBuilder,然后ModuleBuilder,然后TypeBuilder。接下来定义了一个域,得到一个FieldBuilder。如开头所说,FieldBuilder继承FieldInfo,那么它似乎也应该可以用于反射?马上try一下,却得到NotSupportedException。此路不通。
接下来的部分就有趣了。FieldBuilder虽然不能用于反射,但它仍然持有正确的metadata token;而从metadata就可以找出“真正”的FieldInfo。代码中第38的调用完成了这个工作。可以看到,这个方法得到的FieldInfo与通过正常反射得到的FieldInfo是同一个对象,自然就可以用于反射了。
先前跟老赵在twitter上的对话:
老赵误解了我想说的“不能用于反射”的意思。Builder系列类型当然可以用于在生成IL时使用,因为那就是它们的本职工作——Emit。生成的IL在执行的时候并不会使用Builder系列类型的实例通过反射去取值/设值/调用等,当然没问题。一旦想把Builder系列直接用于Emit之外的用途,就会遇到NotSupportedException。
上面提到的转换,再举几个例子:
Metadata是以module为单位组织的,token只在module内部有效。所以ResolveXXX系列的方法也都是在ModuleBuilder上。
这种通过token去获取用于反射的Info系列类型的方法,比通过正常的反射API更高效易用。所以如果是刚动态创建出类型,手上还有Builder系列类型的实例的引用,就不必绕圈通过正常反射获取Info系列类型的实例了。
Builder系列(派生类) | Info系列(基类) |
System.Reflection.Emit.AssemblyBuilder | System.Reflection.Assembly |
System.Reflection.Emit.ModuleBuilder | System.Reflection.Module |
System.Reflection.Emit.TypeBuilder | System.Type |
System.Reflection.Emit.EnumBuilder | System.Type |
System.Reflection.Emit.GenericTypeParameterBuilder | System.Type |
System.Reflection.Emit.FieldBuilder | System.Reflection.FieldInfo |
System.Reflection.Emit.MethodBuilder | System.Reflection.MethodInfo |
System.Reflection.Emit.ConstructorBuilder | System.Reflection.ConstructorInfo |
System.Reflection.Emit.PropertyBuilder | System.Reflection.PropertyInfo |
System.Reflection.Emit.EventBuilder | System.Object |
(最后一个不是Info系列的,所以用灰色表示了。前面的Assembly、Module和Type都算在“广义的Info系列”里)
那么通过SRE创建出一个类型之后,手上的Builder系列类型可以直接用于反射吗?
答案是:不行,Builder系列唯一的使命就是Emit,没有别的用途。
看个例子就明白:demo.cs
using System; using System.Reflection; using System.Reflection.Emit; static class Demo { static void Main(string[] args) { var assemblyName = new AssemblyName("DemoAssembly"); var assemblyBuilder = AppDomain.CurrentDomain .DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); var moduleBuilder = assemblyBuilder.DefineDynamicModule( "DemoAssembly" ); var typeBuilder = moduleBuilder.DefineType( "TestType00", TypeAttributes.Public); var fieldBuilder = typeBuilder.DefineField( "x", typeof(int), FieldAttributes.Private); var testType = typeBuilder.CreateType(); // get a FieldInfo through normal reflection var fieldInfo = testType.GetField( "x", BindingFlags.NonPublic | BindingFlags.Instance); // create new instance of TestType00 var instance = Activator.CreateInstance(testType); // set the field x through normal reflection fieldInfo.SetValue(instance, 2); try { // try to get the field x through FieldBuilder // a FieldBuilder is a FieldInfo, but this won't work... Console.WriteLine(fieldBuilder.GetValue(instance)); } catch (Exception e) { Console.WriteLine(e); //System.NotSupportedException: The invoked member is not supported in a dynamic module. // at System.Reflection.Emit.FieldBuilder.GetValue(Object obj) // at Demo.Main(String[] args) in d:\demo.cs:line 29 } // get a FieldInfo from a FieldBuilder var fieldInfoFromResolved = moduleBuilder.ResolveField( moduleBuilder.GetFieldToken(fieldBuilder).Token); // WARNING: can't call resolve before calling CreateType, // because resolving a type will load the type; an unfinished // type cannot be loaded Console.WriteLine(fieldInfo == fieldInfoFromResolved); // true // get the field x through converted FieldInfo Console.WriteLine(fieldInfoFromResolved.GetValue(instance)); // 2 // set the field x through converted FieldInfo fieldInfoFromResolved.SetValue(instance, 5); // get the field x through normal reflection Console.WriteLine(fieldInfo.GetValue(instance)); // 5 } }
稍微解释一下这段代码:
开头的部分都是很常见的SRE boilerplate,先得到AssemblyBuilder,然后ModuleBuilder,然后TypeBuilder。接下来定义了一个域,得到一个FieldBuilder。如开头所说,FieldBuilder继承FieldInfo,那么它似乎也应该可以用于反射?马上try一下,却得到NotSupportedException。此路不通。
接下来的部分就有趣了。FieldBuilder虽然不能用于反射,但它仍然持有正确的metadata token;而从metadata就可以找出“真正”的FieldInfo。代码中第38的调用完成了这个工作。可以看到,这个方法得到的FieldInfo与通过正常反射得到的FieldInfo是同一个对象,自然就可以用于反射了。
先前跟老赵在twitter上的对话:
@rednaxelafx 写道
@jeffz_cn TypeBuilder不能直接用于反射,FieldBuilder不能用于Get/SetValue,MethodBuilder不能直接用于Invoke……一切都是因为metadata token……
@jeffz_cn 写道
@rednaxelafx FieldBuilder可以用来Stfld的,我的Eazy里刚用过,呵呵。你可以去获取代码看看,https://eazy.svn.codeplex.com/svn 在TypeBuilderExtensions.cs的79行。
老赵误解了我想说的“不能用于反射”的意思。Builder系列类型当然可以用于在生成IL时使用,因为那就是它们的本职工作——Emit。生成的IL在执行的时候并不会使用Builder系列类型的实例通过反射去取值/设值/调用等,当然没问题。一旦想把Builder系列直接用于Emit之外的用途,就会遇到NotSupportedException。
上面提到的转换,再举几个例子:
var type = moduleBuilder.ResolveType(moduleBuilder.GetTypeToken(typeBuilder).Token); var fieldInfo = moduleBuilder.ResolveField(moduleBuilder.GetFieldToken(fieldBuilder).Token); var methodInfo = moduleBuilder.ResolveMethod(moduleBuilder.GetMethodToken(methodBuilder).Token);
Metadata是以module为单位组织的,token只在module内部有效。所以ResolveXXX系列的方法也都是在ModuleBuilder上。
这种通过token去获取用于反射的Info系列类型的方法,比通过正常的反射API更高效易用。所以如果是刚动态创建出类型,手上还有Builder系列类型的实例的引用,就不必绕圈通过正常反射获取Info系列类型的实例了。
发表评论
-
C#的任意类型转换
2010-09-22 19:37 0用之前的恶搞办法制造一个Func<T, U>委托来 ... -
timer与GC
2010-02-25 21:54 0CLR via C# 3rd的第21章讲解了GC相关的内容。其 ... -
CLR中值类型的实现,几个小测试
2009-12-07 17:35 0http://blogs.msdn.com/clrcodege ... -
Array.Copy()
2009-12-02 23:03 0using System; namespace Cons ... -
关于GC.KeepAlive()
2009-12-01 23:16 0调用GC.KeepAlive()确实跟调用自己写的NoInli ... -
native code一样的方法就是一样的么?
2009-10-10 11:42 0GC map EH SOS -
反射还真会挂……
2009-09-22 22:44 3098呃,CLR的反射也可以注入字符串……看来这里也有可玩的突破口 ... -
CLI中方法的局部变量声明
2009-09-15 10:36 0.locals init( int32 val ... -
要让CLR挂掉的话(第二弹)……
2009-09-04 03:26 12879(Disclaimer:如果需要转 ... -
要让CLR挂掉的话……
2009-09-02 16:53 4785(Disclaimer:如果需要转载请先与我联系。 作者:Re ... -
JIT与观察调用栈
2009-07-04 03:53 0Massimiliano Mantione在他的Chasing ... -
CLR上的接口调用也是在运行时检查的
2009-06-02 17:14 2704作者:RednaxelaFX 主页:http://rednax ... -
值类型上的实例方法
2009-05-29 22:15 0.NET里任何实例方法都有一个隐含的this作为第一个参数,无 ... -
call与callvirt、虚方法与非虚方法的组合
2009-05-29 21:31 0Chris Brumme: Virtual and non-v ... -
CLR 2.0的callsite caching
2009-05-29 01:52 0根据http://blogs.msdn.com/vancem/ ... -
.NET中各种黑历史般的名字
2009-05-24 04:29 0dotnetfx: .NET Frameworks COM+ ... -
.NET 4的新动向
2009-05-23 19:58 0http://weblog.ikvm.net/PermaLin ... -
.NET Framework 4 Beta 1与对应的IronPython 2.6的下载
2009-05-21 02:43 1817与先前报导的一致,微软在今天放出了.NET Framework ... -
自己关于VM的帖的目录
2009-04-07 14:02 69647JavaEye的blog系统只允许把帖放到单一类别下,而不能用 ... -
LINQ与DLR的Expression tree(5):用lambda表达式表示常见控制结构
2008-10-01 00:34 12231(Disclaimer:如果需要转载请先与我联系 作者:Red ...
相关推荐
《Google SRE:运维解密》是一份深入探讨Google Site Reliability Engineering(SRE)实践的教程,旨在为那些有志于投身SRE领域的人提供宝贵的洞见。SRE是Google提出的一种工程方法论,它将传统的系统运维与软件工程...
SRE Google运维解密-中文版 SRE Google运维解密-中文版
从 ITIL 到 SRE - 唯品会运维自动化实践 本文主要介绍了唯品会从 ITIL 到 SRE 的运维自动化实践经验,涵盖了 ITIL 的建设方法、瓶颈、困境、自动化和 SRE 尝试等方面。 一、ITIL 的建设方法及瓶颈 唯品会整个...
从SRE的角度来分析eBPF,能给其工作带来一系列的Tracing以及可观测方面的性能提升
为了让亿万用户使用到稳定可靠的服务,Google 组建了一支专业的团队负责运行这些后端服务,这些工程师有一个共同的名字:Site Reliability Engineer。了解 Google SRE 的人常说的一句话是:和你们相比,大部分公司还...
在IT行业中,SRE(Site Reliability Engineering,网站可靠性工程)是一种综合了软件工程与系统运维的实践,致力于提供高可用、高性能、可扩展的在线服务。在这个领域,"SRE系统辅助工具 好帮手"可能是指一种用于...
今年我们花了一点额外的时间进行研究,因为新冠肺炎的大流行给SRE角色的工作增加了一层复杂性。今年的报告从一个独特的角度展示了IT服务工作如何适应远程IT时代。 下载《2020年SRE报告》,了解在向远程IT转变的过程...
google sre 运维解密,为了积分不容易,希望大家支持~~~
标题"SRE_NFINDR_FCLS_高光谱_"指的是一个与高光谱数据分析相关的项目,其中包含了三个主要的算法工具:SRE(Spectral Resolution Estimation,光谱分辨率估计)、NFINDR(Number of Findable Components in a ...
总结,SRE系列太阳能充放电控制器是用于太阳能系统的智能设备,它不仅实现了高效、安全的电力转换,还能根据环境条件自动调整工作模式,从而最大化利用太阳能资源,保护蓄电池,提高系统的整体性能和寿命。
如果Cisco SRE未在出厂时预先安装,则需手动安装到Cisco 2900系列或Cisco 3900系列ISG2路由器中。具体步骤包括: 1. **物理安装**:根据“Cisco Internal Service Module - Services Ready Engine 安装指南”中的...
更新SRE到968 其他基本上不变
SRE工作涉及到多个关键领域,包括监控、自动化、容量规划、故障恢复、事件管理以及服务级别目标(Service Level Objectives,SLOs)。以下是这些领域的详细解释: 1. **监控**:SREs利用各种工具和技术对系统的运行...
在IT行业中,SRE(Site Reliability Engineering,网站可靠性工程)是一种将软件工程方法应用于运维领域的实践,旨在确保系统的高可用性、可扩展性和安全性。SRE2.5可能指的是某个SRE工具或实践的2.5版本,它专注于...
SRE也被称为站点可靠性工程师,就是通过在运营中使用软件开发的背景来处理基础结构问题。 企业需要可靠的系统来竞争和做出准确的决策。
【Qt开发的开源远程控制软件(SRE)】 Qt是一个跨平台的应用程序开发框架,它由The Qt Company提供,并在GNU Lesser General Public License (LGPL)和商业许可证下发布。Qt使得开发者能够用C++语言编写一次代码,...
SRE++Google运维解密
这涉及到对历史数据的分析、业务趋势的理解以及对技术趋势的洞察。 9. **变更管理**:SREs负责变更过程的管理和风险评估,确保每次变更都经过充分的测试和验证,降低引入新问题的风险。 10. **文化与价值观**:SRE...