【问题标题】:Create instance without constructor via Reflection.Emit - possible?通过 Reflection.Emit 创建没有构造函数的实例 - 可能吗?
【发布时间】:2014-04-02 09:32:45
【问题描述】:

我最近开始学习 Reflection.Emit,因此我可以替换所有 Activator 用法,从而在我的代码中获得更好的性能。我目前正在考虑某种序列化和反序列化库。特别是对于反序列化,我想重新创建与序列化之前完全相同的对象状态(我假设序列化是 100% 正确的)。但是,例如可以有一个类,它有多个构造函数,每个构造函数都做一些复杂的事情,因为这个对象具有复杂的逻辑并且必须以某种特定的方式进行初始化。但是,当我对对象的所有内容进行序列化后,我能做的最简单的事情就是绕过任何提供的 ctors - 只需创建一个空对象并用数据填充它的所有字段。期间。

不幸的是,在ILGenerator.Emit 中使用OpCodes.Newobj 需要将ConstructorInfo 作为参数传递。对于结构来说这很容易,因为它们总是有默认的无参数 ctor。但是对于类,情况有所不同。

我将不胜感激。

【问题讨论】:

  • 一定是可以的,因为BinaryFormatter创建对象而不调用构造函数。

标签: performance reflection constructor instance reflection.emit


【解决方案1】:

这一定是可能的,因为 BinaryFormatter 在不调用构造函数的情况下创建对象。

您可以使用FormatterServices.GetSafeUninitializedObject。这可能受到最高安全要求的保护。

【讨论】:

  • 谢谢,工作得很好,虽然它持续了大约 100us,这已经差不多了。但是现在我可以使用 Reflector 来查看内部,也许我可以获得更多的性能:)
  • 如果你发现了什么,请告诉我。
  • 其实我确实发现了一些东西: 1.里面有一个叫做nativeGetUninitializedObject的方法,它实际上是一个黑盒,因为它是extern。我在这里找到了一些关于它的东西:stackoverflow.com/questions/4866179/… 但是它并不多: 2. 我做了更多的性能检查,似乎 GetSafeUninitializedObject 非常不确定。运行一次确实持续了大约 100us,但是当它运行超过 1000 次时,它只持续了几个 Ticks,大约 10000 甚至更多 - 不到 2 Ticks(即小于 200ns)。
  • 很难相信它会这么慢。它是序列化基础架构的关键部分。如果它很慢,它会显示在分析器结果中并被优化。序列化是 10 年前的一项关键技术。
  • 您可以尝试私有的 RuntimeTypeHandle.Allocate。使用 Delegate.CreateDelegate 创建访问器委托。我在reflectioninvocation.cpp 中找到了它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-30
  • 1970-01-01
  • 2015-09-26
相关资源
最近更新 更多