Reflection.Emit 的实际用途

发布于 2024-08-22 07:11:13 字数 304 浏览 15 评论 0原文

在我读过的所有反思书籍中,他们经常说,在很多情况下,您想要即时生成 IL 的情况并不多,但他们没有给出任何示例来说明它在哪里确实有意义。

在看到 Reflection.Emit 作为游戏公司的工作要求后,我很好奇它还被用在什么地方。

我现在想知道您在现实世界中是否见过任何情况,这是否是问题的最佳解决方案。也许它被用作设计模式的实现?

注意 我想 PostSharp / AOP 使用它。

In all the books I've read on reflection they often say that there aren't many cases where you want to generate IL on the fly, but they don't give any examples of where it does make sense.

After seeing Reflection.Emit as a job requirement for a gaming company I was curious where else it's being used.

I'm now wondering if there are any situations you've seen in the real world were it was the best solution to the problem. Perhaps it is used as an implementation to a design pattern?

Note
I imagine PostSharp / AOP uses it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(17

傲娇萝莉攻 2024-08-29 07:11:14

Reflection.Emit 命名空间用于开发 LinqPad。它有助于动态创建类型化的 Datacontext。查看此链接 http://www.linqpad.net/HowLINQPadWorks.aspx

Reflection.Emit namespace is used to develop LinqPad.It helps to create typed Datacontexts dynamically. Check out this link http://www.linqpad.net/HowLINQPadWorks.aspx.

梦里兽 2024-08-29 07:11:14

例如,实体框架使用Reflection.Emit在运行时构建代理类,该类继承自模型类以提供延迟加载 >更改跟踪

For instance Entity Framework uses Reflection.Emit to build proxy classes at run-time which inherit from your model classes to provide lazy loading and change tracking.

笙痞 2024-08-29 07:11:14

从外部数据生成枚举:

C# 中的动态枚举

在该示例中数据来自查找数据库,枚举是在编译时通过从数据库中读取来创建的。这可以保持类型安全,而无需手动维护重复的信息源。

Generating enums from external data:

Dynamic enum in C#

In that example the data comes from a lookup database and the enum is created at compile-time by reading out of the database. This maintains type-safety without having to manually maintain duplicate sources of information.

酒绊 2024-08-29 07:11:14

我实际上正在开发自己的语言,并且正在使用 .NET Framework 的 Reflection.Emit 构建其编译器。
有人可能认为使用 C# 构建编译器不好,但实际上一切正常,并且编译时性能足够好。另外,这显然与运行时性能完全无关,运行时性能取决于 CLR,而不是我的编译器(除了像运算符优先级这样的最小优化)。
完成后我会立即将其发布到 GitHub 上。

I'm actually developing my own language and I'm building its compiler using .NET Framework's Reflection.Emit.
Someone could think that building a compiler using C# is not good, but things are actually working fine and compile-time performances are good enough. Also, this is obviously not related at all to the runtime performances, which will depend upon CLR, not my compiler (except for minimal optimization like operator precedence).
I'll publish it on GitHub as soon as I'll have completed it.

小红帽 2024-08-29 07:11:14

我喜欢探索更多 AI-Inspired 的自学方式。它允许我们在运行时创建一个类或模块

I like to explore more for AI-Inspired for self-learning. It allows us to create a class or module at run-time

黯然#的苍凉 2024-08-29 07:11:13

Expression.Compile 本质上就是这样做的 - 这是 LINQ 的某些的关键。

我目前正在使用反射发射来重写序列化 API - 因为有时反射还不够好。碰巧这也将允许它生成 dll(很像 sgen 的工作方式),允许完全静态代码(我希望这将使它对 iPhone 友好)。

我还在 HyperDescriptor 中使用类似的方法来提供非常快速的基于名称的属性 -抬头。

我还使用emit来做类似的事情:

所有与SO问题相关的问题。

最后,这种IL方法是protobuf-net“v2”的核心;这里的原因是它允许我两者在运行时拥有一个快速模型(通过IL动态编译它),并且将相同的直接写入静态 -编译 dll,以便它可以在 iPhone、Phone 7 等(缺乏必要的元编程 API)上运行。

Expression.Compile essentially does this - that is key to some of LINQ.

I am currently using reflection emit to re-write a serialization API - because sometimes reflection just isn't good enough. As it happens this will also allow it to generate dlls (much like how sgen works), allowing fully static code (I'm hopeful this will make it iPhone friendly).

I also use a similar approach in HyperDescriptor to provide very fast name-based property-lookup.

I've also used emit to do things like:

all related to SO questions.

Finally, this IL approach is the core of protobuf-net "v2"; the reason here is that it allows me both to have a fast model at runtime (compiling it via IL on the fly), and to write the same directly to a static-compiled dll, so that it works on things like iPhone, Phone 7, etc (which lack the necessary meta-programming APIs).

淡淡绿茶香 2024-08-29 07:11:13

动态生成实现某些接口的 模拟对象。执行此操作的示例框架:moqrhino 模拟

Dynamically generating a mock object which implements some interface. Example frameworks which do this: moq, rhino mocks.

听你说爱我 2024-08-29 07:11:13

我使用它作为动态创建动态代理来包装类的方法。 NHibernate 使用相同的模式来代理对 POCO 对象的调用,以代替查询数据库。

任何时候您希望能够动态地“编写代码”(即创建新函数等),您都需要Emit

I'm using it as a way to create dynamic proxies on the fly to wrap a class. NHibernate uses this same pattern to proxy calls to POCO objects to instead query a database.

Any time you want to be able to "write code" (i.e. create a new function, etc.) dynamically, you'll need Emit.

丶视觉 2024-08-29 07:11:13

Castle DynamicProxy 将其用于动态代理。然后,Castle 的 IoC 容器 Windsor 和 OR 映射器 ActiveRecord 使用 DynamicProxy。

Castle DynamicProxy uses it for, you guess, dynamic proxies. DynamicProxy is then used by the Castle's IoC container Windsor and OR mapper ActiveRecord.

亽野灬性zι浪 2024-08-29 07:11:13

DLR 和 DLR 相关语言严重依赖 Reflection.Emit

The DLR and DLR related languages heavily rely on Reflection.Emit

空‖城人不在 2024-08-29 07:11:13

我记得在第 8 章中看到过 Relection.Emit漂亮的代码。基本上,作者专门设计了一个函数,用于对给定图像执行一组特定的图像处理操作,从而大大减少执行时间。

I remember seeing Relection.Emit used in chapter 8: "On-the-Fly Code Generation for Image Processing" of Beautiful Code. Basicly the author specializes a function for doing a certain set of image processing operations on a given image, which in turn leads to greatly reduced execution time.

躲猫猫 2024-08-29 07:11:13

我在一个必须通过反射重复访问属性的应用程序中使用过它(因为属性名称在编译时未知)。

通过在运行时创建一个帮助程序类来生成访问该属性的代码,生成的代码比原始的仅反射代码快了一个数量级。

I've used it in an application where a property had to be accessed repeatedly via reflection (because the property name was not known at compile time).

By creating a helper class at runtime that generates code to access the property, the resulting code was an order of magnitude faster than the original reflection-only code.

无人问我粥可暖 2024-08-29 07:11:13

XMLSerializer 实际上会生成代码并在第一次运行时对其进行编译。如果满足以下条件,您可以阅读 Scott Hanselman 网站上这篇精彩的博客文章,了解如何调试 XML 序列化:你知道这正在发生。

The XMLSerializer actually generates code and compiles it on first run. You can read this great blog post on Scott Hanselman's site regarding how to debug XML Serialization if you know this is happening.

古镇旧梦 2024-08-29 07:11:13

模拟库还使用 Reflection.Emit 生成单元测试中使用的代理。

Mocking libraries also use Reflection.Emit to generate proxies used in Unit Testing.

最后的乘客 2024-08-29 07:11:13

我最近使用它创建了一个概念验证,用于编译一组在运行时执行成本非常昂贵的操作,并实现了 200% 的速度提升。这些操作是使用 RegEx 来解析一个大字符串,并循环匹配,使用 Reflection 来查找和实例化类型,以及其他一些不太快的事情。通过使用 IL 发出,我创建了与委托类型匹配的动态函数(使用 DynamicMethod)并缓存它们。我对每个输入值执行一次正常的 RegEx/Reflection dance,以弄清楚它应该做什么,然后使用 StringBuilder 将字符串连接为文字,并且现在我可以在发出的 IL 中使用实际类型本身,而不是 Reflection/Activator。这里有一个有用的提示:不要尝试自己编写 IL,除非你是一个施虐受虐狂。用 C# 编写一个示例函数或类型来执行您想要的操作,对其进行编译,然后使用 Reflector 或 ILDASM 查看生成的 IL。然后使用Emit来做类似的逻辑。另一个提示是您可以创建本地变量并将它们存储到变量中,然后使用 Emit(OpCodes.Ldloc, myLocalVar) 它将为您获取本地地址,而不必跟踪本地索引(即 ldloc_1)。

I have recently used it to create a proof of concept for compiling a set of operations that's very expensive to do at runtime, and achieved a 200% improvement in speed. The operations were to use RegEx to parse a large string, and loop over the matches, use Reflection to find and instantiate types, and a bunch of other things that aren't exactly fast. By using IL emit, I created dynamic functions that matched a delegate type (using DynamicMethod) and cached them. I did the normal RegEx/Reflection dance once per input value to figure out what it should do, then used StringBuilder to concatenate the strings as literals, and instead of Reflection/Activator I now could use the actual types themselves in the emitted IL. Here's a helpful tip: don't try to write IL yourself unless you're a sado-masochist. Write a sample function or type in C# that does what you want, compile it, and use Reflector or ILDASM to see the generated IL. Then use Emit to do similar logic. Another tip is you can create locals and store them to variables, then use Emit(OpCodes.Ldloc, myLocalVar) and it'll get the local address for you, instead of having to keep track of the local index (i.e. ldloc_1).

穿越时光隧道 2024-08-29 07:11:13
  1. 生成声明性代码,例如使用接口来声明底层 HTTP REST 服务。 https://github.com/neurospeech/retro-core-fit

  2. 性能助推器,大多数时候我使用Expression.Compile来创建代码片段,通过编译将表达式提供给将来可以执行的已编译委托来快速检索信息。如果您使用PropertyInfo.GetValue,它会非常慢,但是如果您创建一个表达式来访问属性并将其编译为委托(内部使用Reflection.Emit),则会节省大量CPU时间.

  1. Generate declarative code, such as using interface to declare underlying HTTP REST service. https://github.com/neurospeech/retro-core-fit

  2. Performance booster, most of the time I use Expression.Compile to create a fragment of code to retrieve information quickly by compiling giving expression to compiled delegate which can be executed in future. If you use PropertyInfo.GetValue, it is very slow, but if you create an expression to access property and compile it to a delegate (which internally uses Reflection.Emit), it is huge savings on CPU time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文