问题标签 [reflection.emit]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
4 回答
3586 浏览

cil - 是否可以在堆栈上间接加载值类型

在 Microsoft IL 中,要调用值类型的方法,您需要间接引用。假设我们有一个名为“il”的 ILGenerator,并且当前我们在堆栈顶部有一个 Nullable,如果我们想检查它是否有值,那么我们可以发出以下内容:

但是,最好跳过将其保存为局部变量,而只需在堆栈上已经存在的变量地址上调用该方法,例如:

ldind 指令系列看起来很有希望(尤其是 ldind_ref),但我找不到足够的文档来知道这是否会导致值的装箱,我怀疑它可能会。

我看过 C# 编译器的输出,但它使用局部变量来实现这一点,这让我相信第一种方法可能是唯一的方法。有人有更好的想法吗?

****编辑:附加说明****

尝试直接调用该方法,如以下程序中注释掉的行,不起作用(错误将是“操作可能破坏运行时”)。取消注释这些行,您会看到它确实按预期工作,返回“True”。

因此,您不能简单地使用堆栈上的值调用方法,因为它是值类型(尽管如果它是引用类型,则可以)。

我想要实现(或知道是否可能)是替换显示注释掉的三行,但保持程序正常工作,而不使用临时本地。

0 投票
6 回答
9729 浏览

.net - 修改现有的 .NET 程序集

有没有办法修改现有的 .NET 程序集而不求助于 3rd 方工具?我知道PostSharp使这成为可能,但我发现 PostSharp 的开发人员基本上必须重写整个System.Reflection命名空间的功能才能使现有程序集可修改,这非常浪费。

System.Reflection.Emit只允许创建新的动态程序集。但是,这里使用的所有构建器类都继承自基本反射类(例如TypeBuilder,继承自System.Type)。不幸的是,似乎没有办法将现有的、动态加载的类型强制到类型构建器中。至少,没有官方支持的方式。

那么不支持怎么办?有谁知道允许将现有程序集或类型加载到此类构建器类中的后门?

请注意,我不是在寻找修改当前程序集的方法(这甚至可能是一个不合理的请求),而只是为了修改从光盘加载的现有程序集。我担心没有这样的事情,但我还是想问一下。

在最坏的情况下,人们不得不求助于ildasm.exe反汇编代码然后ilasm.exe重新组装,但是.NET 中没有包含工具链(阅读:IL 阅读器)来处理 IL 数据(或者是否存在?)。

/编辑:

我没有具体的用例。我只是对通用解决方案感兴趣,因为修补现有程序集是一项非常常见的任务。以混淆器、分析器或 AOP 库为例(是的,后者可以以不同的方式实现)。正如我所说,被迫在System.Reflection.


@楔:

你是对的。但是,这里没有特定的用例。我已经修改了原始问题以反映这一点。另一个问题引发了我的兴趣,提问者想知道如何在每个方法的末尾注入指令popret以防止 Lutz Roeder 的 Reflector 重新设计(VB 或 C#)源代码。

现在,这个场景可以通过许多工具来实现,例如上面提到的 PostSharp 和用于 Reflector 的Reflexil插件,而后者又使用Cecil库。

总而言之,我只是对 .NET 框架不满意。

@乔尔:

是的,我知道这个限制。无论如何,感谢您指出它,因为它很重要。

@马克思达德:

这似乎是唯一可行的方法。但是,这意味着您仍然必须使用构建器类重新创建完整的程序集,对吗?即,您必须手动遍历整个组件。

嗯,我会调查的。

0 投票
2 回答
2283 浏览

.net - 使用 .NET 的 Reflection.Emit 生成接口

我需要在运行时生成一个具有与现有接口相同的所有成员的新接口,除了我将在某些方法上放置不同的属性(某些属性参数直到运行时才知道)。如何实现?

0 投票
2 回答
1074 浏览

.net - 程序集未正确保存

我有一些非常简单的代码来生成程序集并在包含的类型上调用方法。该方法被调用并正确运行,但是当我使用反射器查看生成的程序集时,我看不到类型。

下面是示例代码:

这是Reflector的相应反汇编:

... 和 ...

谁能帮我正确保存程序集?

0 投票
6 回答
17885 浏览

.net - 呼叫和 Callvirt

CIL 指令“Call”和“Callvirt”有什么区别?

0 投票
4 回答
11789 浏览

c# - 如何在运行时向方法添加属性?

我们使用 Microsoft.Practices.CompositeUI.EventBroker 在我们的应用程序中处理事件订阅和发布。可行的方法是向事件添加一个属性,指定一个主题名称,如下所示:

然后向处理程序添加另一个属性,具有相同的主题名称,如下所示:

然后你将你的对象传递给一个匹配所有东西的 EventInspector。

我们需要对此进行调试,因此我们正在尝试创建一个订阅所有事件的调试类。我可以获得所有主题名称的列表......但仅限于运行时。因此,在将调试对象传递给 EventInspector 之前,我需要能够在运行时向方法添加属性。

如何在运行时向方法添加属性?

0 投票
3 回答
1858 浏览

c# - 调用基类的事件处理程序的 MSIL 是什么?

我有一个名为 EventConsumer 的类,它定义了一个事件 EventConsumed 和一个方法 OnEventConsumed,如下所示:

我需要在 OnEventConsumed 运行时添加属性,所以我使用 System.Reflection.Emit 生成一个子类。我想要的是与此等效的 MSIL:

我到目前为止是这样的:

我创建类型,创建类型的实例,并调用它的 OnEventConsumed 函数,然后我得到:

...这并不完全有帮助。我究竟做错了什么?调用基类的事件处理程序的正确 MSIL 是什么?

0 投票
2 回答
714 浏览

.net - AppDomain 创建速度有多快?

我刚刚发现,如果通过 Reflection.Emit 生成程序集,.NET 框架会将引用保存在一个静态成员中,以防止 Reflection.Emit 类不被 GC'ed。

由于限制,我无法使用 DynamicMethod。我还在程序过程中生成了很多程序集(IronScheme 的增量编译器)(可能是 1000+)。

因此,我想只在一个单独的域中处理代码生成,然后再将其卸载(尚未决定如何处理)。

有没有人有任何经验这会有多贵?

0 投票
2 回答
1809 浏览

c# - 使用 Reflection.Emit 的奇怪参数序列

我最近一直在看 Reflection.Emit。我写了一个简单的程序,它生成一个 DynamicMethod ,它简单地调用另一个具有相同参数的方法

当我运行此示例时,我希望它输出 1,2,3,4,5,6 但是,它输出 2,3,4,5,6,1

我不太清楚为什么......如果你们知道使用 Reflection.Emit 的任何好的资源,你能指出我那个方向吗?我一直在使用 Reflector 和 Emit AddIn。

干杯

罗汉

0 投票
3 回答
7608 浏览

c# - 查找所有程序集依赖项,反射器样式

我正在使用 Reflection.Emit 即时生成一个程序集,然后保存它。它包含一个 Type 和一个静态 Main() 方法。

.NET 可以自动引用所需的程序集。但是,在 Main() 中,调用了来自另一个程序集的方法,并且没有以标准方式引用它。

执行程序集时,运行时查找此程序集但找不到它,这是一个问题。

Reflector 可以检测到这一点,并在“依赖”列表下显示这个额外的程序集。如何使用反射 API 检索这些隐式依赖项?

谢谢