为什么私人常数存储在.NET组件中?
代码引用的常数被编译到IL时被其实际值所取代. 由于可以在特定组件之外的代码引用公共常数,因此将它们存储在大会的元数据中是有道理的. 但是为什么私人常数存储在那里?在定义它们的大会中,没有提及代码IL中的那些常数,也没有在大会之外被引用. . 那么,在编译了代码后需要访问这些值? 在我看来,所有集会中的所有常数都应是公开的,私人常数应该是一种语言级别的功能,它仅会导致编译器发出文字价值. 解决方案 C#编译器可以优化 的私人内容.不只是常数.它可以删除未使用的成员,类,代码.它可以剥离私人名称.它可以删除私人属性并用方法替换它们.等. 反思访问和IL重写工具是私人物品的重要用例.另外,当大多数元数据仍然存在时,调试会更容易.例如,您可以使用编辑并继续使用以前未使用的成员.您可以使用直接窗口调用静态未使用的成员. 也许对PDB符号也有影响. 请注意,.NET组件包含大量 的元数据,对反射访问有用.属性除了进行检查以外,根本没有其他含义.集
34 2024-01-08
编程技术问答社区
从IL中创建一个方法的副本
我正在尝试在运行时使用反射创建方法的副本. 我有以下代码. public static R CopyMethod(Func f, T t) { AppDomain currentDom = Thread.GetDomain(); AssemblyName asm = new AssemblyName(); asm.Name = "DynamicAssembly"; AssemblyBuilder abl = currentDom.DefineDynamicAssembly(asm, AssemblyBuilderAccess.Run); ModuleBuilder mbl = abl.DefineDynamicModule("Module"); TypeBuilder tbl = mbl.DefineType("Type"); var info = f.GetMethodInfo(); M
2 2024-01-08
编程技术问答社区
为什么C#->CIL的每条指令都有一个标签?
在编译C#程序上使用Ildasm.exe时,它表明方法中的每个说明都有一个标签. 例如: IL_0001: ldc.i4.4 IL_0002: stloc.0 IL_0003: ldc.r8 12.34 IL_000c: stloc.1 IL_000d: ldc.r8 3.1415926535897931 IL_0016: stloc.2 IL_0017: ldstr "Ehsan" IL_001c: stloc.3 IL_001d: ret 为什么?执行此操作不是效率低下还是CIL编译器优化这些标签本身? 解决方案 标签不存在于编译的CIL中.为了方便您在分解代码中显示它们. 这些特定的标签对应于指令偏移,而手工制作的代码没有这种限制(标签可能是任意字符串). 其他解决方案 在编译的IL中,没有标签.相反,跳跃指令从以下说明开始时使用相对偏移. 例如,考虑这个微不足道的C#函数: public
2 2024-01-08
编程技术问答社区
在Silverlight和Windows Phone 7中是否支持模块初始化器?
如果您愿意操纵IL .NET支持模块初始化器 http://blogs.msdn.com/B/Junfeng/Archive/2005/11/19/494914.aspx Silverlight和Windows Phone 7? 是否支持模块初始化器? 解决方案 仅C ++/CLI支持模块初始化器.这只是间接的,它使用它们来使CRT启动并获得不受管理的变量和对象初始化.您必须在IL中写信.我尝试过,它在Silverlight 4: 上工作正常. .assembly extern mscorlib { .publickeytoken = (7C EC 85 D7 BE A7 79 8E ) .ver 2:0:5:0 } .assembly test { .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor()
4 2024-01-08
编程技术问答社区
为什么x86 JIT比x64更聪明?
我正在运行一个非常简单的程序 static void Main(string[] args) { Console.WriteLine(Get4S()); Console.WriteLine(Get4()); } private static int Get4S() { return 4; } private static int Get4() { int res = 0; for (int i = 0; i
0 2024-01-08
编程技术问答社区
条件属性是如何工作的?
我有一些用[Conditional("XXX")]标记的辅助方法.目的是在仅存在XXX条件编译符号时将方法进行条件编译.我们将其用于调试和跟踪功能,并且运行良好. 在我对条件汇编的工作方式的研究期间,我发现有几个来源说明用Conditional属性标记的方法将放置在IL中,但不会执行对方法的调用. 如何将代码汇编成IL但未执行?我该如何实际验证行为实际上是所描述的?我对IL没有做太多事情,所以我的技能在这个领域很弱. 解决方案 这是由编译器控制的.所有具有[Conditional]的方法仍将包含在MSIL中,但将包括.custom instance行,详细介绍[Conditional].在编译时,用于呼叫者的编译器Lexes,然后进行语义分析和超载分辨率,并在您放置[Conditional]上的方法中找到.custom instance il.因此,它不会编译呼叫. so:编译器编译了目标方法,但是不会对该方法编译任何调用.注意:该方法仍然存在,您仍然可以对其进
0 2024-01-08
编程技术问答社区
PEVerify能告诉我每个错误的严重程度吗?
我正在使用Mono.Cecil修改程序集,我想检查它是否有效性(结果是否完全运行).我正在尝试使用PEVerify,但是我有问题. 它是为了确保代码可验证的,因此仅说ERROR错误是否意味着IL完全无效并且不会执行,或者它是否是完全信任的可验证性问题.以下是一些示例: 使用指针等. 未设置.locals init当该方法具有当地人时. 来自非构造方法的调用.ctor 使IL无法运行的问题包括: 成员无法从其使用的位置访问. 成员不存在. 有没有办法使我有些迹象表明问题的严重性?如果没有,还有其他工具可以执行此操作吗? 解决方案 @hanspassant已经试图解释它,但是我们都彼此了解,这是正在发生的事情. peverify检查您的组件是否不行.也就是说,Peverify不是JIT编译器. JIT编译器本身没有检查IL组件 - 它只是抓住要调用的方法,将其更改为SSA表单,对其进行优化,对其进行编译,然后调用结果二进制组件. 现在,
2 2024-01-07
编程技术问答社区
从一个程序集中提取特定IL(.NET中间语言)签名的机制
我有一个在Microsoft .NET汇编中找到的大约25种类型的列表,我需要在其中提取班级及其成员的IL签名.我想要每个类型的文件,每个签名在一行上.因此,例如以类型 System.Collections.Generic.Comparer 我想从该类型的组件中提取以下内容(有一些我不需要的私人成员,但是我可以在需要时手动处理该类型). .class public abstract auto ansi serializable beforefieldinit System.Collections.Generic.Comparer`1 extends System.Object implements System.Collections.IComparer, class System.Collections.Generic.IComparer`1 .method family hidebysig specialname rtspecialname ins
4 2024-01-07
编程技术问答社区
Reflector是如何对代码进行反编译的?
红色大门蚂蚁探测器或反射器之类的工具如何将IL转换为c#或vb.net代码? 我最近注意到,红门蚂蚁探测器不会生成最初编写的相同源代码. 它生成了我使用foreach的while循环. 让我思考.我在反射器中打开了反射器.exe本身,但它们的代码大多是(并非全部)混淆. . 解决方案 通过查看IL和构建与IL等同的源代码的源代码,在一般工作中的分解器.这不能总是产生原始源代码,因为IL会丢弃一些高级信息(尽管不如机器代码),并且因为通常有几块代码将其编译到同一IL.例如,a foreach环相当于某种类型的while循环(首先设置枚举器的循环,然后循环直到枚举器耗尽,并在每个步骤中提出枚举者). ) ). ) 其他解决方案 实施解码的一种常见技术是使用"间隔分析"来识别循环的程度. 与成语识别结合在一起,并且模式称为"派生的图序列"时,可以从包含汇编语言(或MSIL)的控制流程图开始,然后迭代地将其简化为止,直到您拥有一个AST(抽象的synt
0 2024-01-07
编程技术问答社区
从IL构建的方法中引用一个集合
我正在使用反射构建动态方法.大多数教程和文档(例如我试图找到一种从动态组件中引用另一个组件的方法. 例如,我希望能够使用Reflection.Emit. 构建以下功能 public static void f(int n) { int[] arr = new arr[n]; return arr.Max(); } 这样做的常见方式是什么? 解决方案 获得有效IL指令的最可靠方法是用高级语言创建您的代码,对其进行编译并对其进行反编译.接下来,您可以使用Reflection.Emit. 重新创建说明 我更改了您的示例功能,否则它无法测试,因为结果将始终相同: public static int f(int n) { int[] arr = Enumerable.Range(0, n).ToArray(); return arr.Max(); } 构建作为调试,iLdasm给了我们(发布会导致更少的说明,但没有太多可见):
2 2024-01-06
编程技术问答社区
"指定的演员无效",只有在从MS构建的发布版上才有。
我在仅执行MSBuild 4.0构建时,"指定的铸件无效".我在使用Visual Studio 2012的发行版本中对此进行了测试,但没有得到这个问题.我还使用MSBuild 4.0的调试构建对此进行了测试,但没有得到此问题. 异常: 代码 public abstract class CachedSessionBase : ISessionObject { protected Dictionary _getAndSetCache = new Dictionary(); protected TResult SetAndGet(ObjectFactory factory, Func func) { StackTrace stackTrace = new StackTrace(); var met
2 2024-01-06
编程技术问答社区
防御性反多线程类实现
我有一个对于多线程应用程序而不是安全(以几种方式),我想提供内部检查以确保无法同时访问关键方法. 问题 我应该采用哪些技术来检测和防止多个线程访问我的班级? 在所有方法,属性等上跟踪线程. 解决方案 只需记录它不是线程安全即可.这就是.net中的类别. 其他解决方案 它会有所帮助吗? lock(_padLock) { .... } ,或者如果您可以外部访问对象,则可以使用Mutex对象. 其他解决方案 您可能使用的最佳内部检查是其他人建议的设置.但是,这里有一些值得调查的创造性方法,看看它们是否解决了您的特定问题.我遇到的问题是,我不知道只有类的部分是不安全的,是否使用类别的类别使用类别的线程.因此,这里有一些减轻某些方案 的组合 方案1:静态类/方法 - 这将确保无论是谁访问静态类/成员,如果另一个线程已经这样做. public static class UnsafeStaticClass { private st
6 2024-01-06
编程技术问答社区
IL / CLR / DLR 参考资料?
我想在引擎盖下了解更多有关IL和CLR/DLR的信息.我的一个朋友推荐了" Microsoft .Net Il Il Il Assembler"一书,但是由于它在2002年问世以来,我担心此时已经过时了. 是否有人有更多最新的书籍或网站可以由了解.NET语言的人可以使用以了解IL和CLR的内部工作? 的更多信息? 解决方案 也许我的答案现在已经很晚了,但是" MS Press -Inside Microsoft .Net Il Il Assembler"的书实际上很棒. 请记住:框架3.x仅添加新的类和功能.基础技术仍然相同.因此,这本书仍然存在,至少直到FW3.5. ecma一边,以及一些艰苦的工作,您拥有所需的一切. 其他解决方案 有关CLR低级细节的有趣查看,我喜欢SSCLI ESSENSION.对于IL/dlr. 并不有用 其他解决方案 ECMA 335 CLI标准好阅读.
0 2024-01-05
编程技术问答社区
是否有一个通用的CIL代码来转换任何类型的实例为字符串?
是否可以编写通用CIL指令,将任何类型(值和参考)的实例转换为System.String? 特别是,我对将这些说明注入方法的单声道范围很感兴趣. 分析我提出的一种单声道的通用方法. (它应该将i-th方法参数转换为字符串) System.Reflection.MethodInfo to_string_method_info = typeof( System.Object ).GetMethod( "ToString" ); Mono.Cecil.MethodReference to_string_reference = injectible_assembly.MainModule.Import( to_string_method_info ); Mono.Cecil.TypeReference argument_type = method_definition.Parameters[ i ].ParameterType; method_definition.Body.Ins
4 2024-01-05
编程技术问答社区
与IL的通用型?
是否可以使用IL Generator使用仿制药? DynamicMethod method = new DynamicMethod( "GetStuff", typeof(int), new Type[] { typeof(object) }); ILGenerator il = method.GetILGenerator(); ... etc 解决方案 是的,这是可能的,但与DynamicMethod类不可能.如果您仅限于使用此课程,那您就不幸了.如果您可以使用MethodBuilder对象,请继续阅读. 出于大多数目的和目的, 发射通用方法的主体与发射其他方法的主体没有什么不同,除了您可以制作通用类型的局部变量.这是使用通用参数t使用MethodBuilder创建通用方法的示例,并创建类型t的本地 MethodBuilder method; //... Leaving out code to
4 2024-01-05
编程技术问答社区
ldstr内部是否实现了newobj?
我们都知道字符串是隐式实例化的,这意味着我们不必使用new来获取一个对象的引用. 因为这样,我一直相信该框架正在照顾这个问题,因此,如果我做这样的事情,我会变得相同: String first = new String(new char[] {'a'}); string second = "a"; 然而,看来第一行是使用newobj instance void [mscorlib]System.String::.ctor(char[])完成的 和第二个ldstr "a". 因此,为了获得字符串参考,ldstr内部调用newobj以及在哪里可以看到规范/详细信息以备份此内容? 解决方案 ldstr为您提供对文字字符串的引用,例如根据文档(请记住,每个默认值是实施字面的字符串,因此仅创建一次).第一个语句按预期使用newobj指令创建常规实例. 其他解决方案 string简单地遵循参考对象类型的基本准则,这就是为什么new上的原因 您看到newobj.
2 2024-01-05
编程技术问答社区
如何控制.Net在命名空间冲突中选择哪个程序集?
由于某种原因,我需要(随身携带)或另一个使用system.text.text.soding名称空间的WinRT版本.我可以手动添加对汇编的引用,但它仍然会使用Mscorlib的实现.而且我显然无法完全删除Mscorlib. 我如何强制我的项目使用winrt的system.text.encoding.dll代替mscorlib? 基本上,我需要它生成这片IL: call class [System.Text.Encoding]System.Text.Encoding [System.Text.Encoding]System.Text.Encoding::get_UTF8() 而不是这样: call class [mscorlib]System.Text.Encoding [mscorlib]System.Text.Encoding::get_UTF8() 解决方案 您需要别名引用.为此,请转到解决方案资源管理器,然后选择要别名的参考.查看属性并编辑别名字段
0 2024-01-05
编程技术问答社区
CIL unbox_any指令-奇怪的行为
.method public static void Test(object A_0) cil managed { // Code size 13 (0xd) .maxstack 1 .locals init (!!T V_0) IL_0000: ldarg.0 IL_0001: isinst !!T IL_0006: unbox.any !!T IL_000b: stloc.0 IL_000c: ret } // end of method DemoType::Test 相等的C#代码是: public static void Test(object o) where T : class { T t = o as T; } 我的问题是: 为什么unbox.如果您只是做 var a = father as child isInst构建会呼叫而没有unbox
4 2024-01-05
编程技术问答社区
发出委托函数调用
我有以下C#代码: public static double f2(Func f, double x) { return f(x); } 这是IL代码: .method public hidebysig static float64 f2 ( class [mscorlib]System.Func`2 f, float64 x ) cil managed { // Method begins at RVA 0x20bd // Code size 8 (0x8) .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: callvirt instance !1 class [mscorlib]System.Func`2
0 2024-01-05
编程技术问答社区