【问题标题】:Why should I care about RTTI in Delphi?为什么我要关心 Delphi 中的 RTTI?
【发布时间】:2011-01-14 02:17:35
【问题描述】:

我听说过很多关于新的/改进的RTTI capabilities of Delphi 2010,但我必须承认我的无知......我不明白。我知道 Delphi 的每个版本都支持 RTTI...而且我知道 RTTI(运行时类型信息)允许我在应用程序运行时访问类型信息。

但是,究竟是什么意思? Delphi 2010 的 RTTI 支持和reflection in .NET 一样吗?

有人能解释一下为什么 RTTI 有用吗?假装我是你的尖头发老板,帮助我理解为什么 RTTI 很酷。我如何在实际应用中使用它?

【问题讨论】:

  • 查找 TMS Aurelius,您会发现 RTTI 属性在创建 ORM 数据库框架和将 XML 序列化为纯对象和相反方面非常有用。

标签: delphi reflection delphi-2010 rtti


【解决方案1】:

Delphi 中的 RTTI 仍然没有相当 像 .NET 或其他托管语言中的反射那样全功能,因为它是在编译代码上运行,而不是中间语言(字节码)。然而,这是一个非常相似的概念,Delphi 2010 中的新 RTTI 系统使其很多更接近反射,暴露了整个面向对象的 API。

在 D2010 之前,RTTI 非常有限。我记得唯一用它做的事情就是将enumerated type to a string(或vice versa)转换为在下拉列表中使用。我可能曾在某一时刻将它用于control persistence

使用 D2010 中的新 RTTI,您可以做更多事情:

  • XML Serialization

  • 基于Attribute 的元数据 (TCustomAttribute)。典型的用例是属性的自动验证和自动权限检查,这两项通常需要您编写大量代码。

  • 添加 Active Scripting 支持(即使用 Windows 脚本控件)

  • 构建插件系统;你以前可以这样做,但是有很多头痛。我无法找到一个从上到下执行此操作的非常好的示例,但所有必要的功能现在都可用。

  • 看起来有人甚至试图为 Delphi 2010 实现 Spring(DI 框架)。

所以这绝对是非常有用的,虽然我不确定你能多好地向 PHB 解释它;它的大部分用途可能将通过 3rd 方库和框架来实现,这与它在当今 .NET 社区中的工作方式非常相似——很少看到反射代码位于业务逻辑中,但典型的应用程序会使用几个基于反射的组件,例如 Object-Relational Mapper 或 IoC 容器。

我回答问题了吗?

【讨论】:

  • 我真的不知道怎么做;属性绝对在 D2010 之前是不可能的(TCustomAttribute 是新的),之前肯定从来没有任何 DI/IoC 框架,XML 序列化几乎是不可能的,因为旧的 RTTI 只能找到 published 属性, Active Scripting 是一个经常被讨论但从未解决的问题。您将如何使用旧的 RTTI 完成其中的任何一项?你有链接到有人把它拉下来吗?如果您说的是真的,我很乐意编辑答案。
  • @Aaronaught:当然属性是可能的,你根本没有编译器的魔法来帮助你,必须提供你自己的“注册表”和查找机制。这些“手动”机制当然可以比 RTTI 提供的通用机制更有效。 XML 序列化同样是完全可能的。我无法提供代码链接,因为它本质上是商业性的,但我可以向您保证,您提到的所有事情都是在 D2010 RTTI 扩展之前很久完成的。
  • @Deltics:我同意你的观点,从技术上讲,任何事情在通用编程语言中都是可能的。如果需要,您可以在 GW Basic 中实现 XML 序列化。区别在于学位之一,而且 - 恕我直言 - 这里的学位相当大。
  • @Mason Wheeler:在评论框中很难完全解释 DI/IoC,但我会再试一次。这不仅仅是抽象数据类型的使用——那些一直存在——它是这些类型的实例化。新的接口不是新的——我也从 D4 开始使用这些接口——而是你从来没有真正创建实现一个的具体类型。容器会为您完成,如果您需要更改应用程序范围内的实现,只需一行代码或配置即可完成,即使构建发生在 100 个不同的地方。
  • 而且,不言而喻,这种事情一直都是可能的,但一直没有可能的是创建一个通用框架来做到这一点,它将集成与任何应用程序。也许这就是翻译中迷失的东西;您可以自己为您个人控制的应用程序做所有这些事情,并且可以轻松地修改和推理;反射(和新的 RTTI)提供的是创建执行这些任务的可重用框架级组件的能力,因此您不必为每个项目重新实现它。
【解决方案2】:

大多数人可能不会在现实世界的应用程序中使用它。

将使用它的人是框架构建者。 DUnit 等框架广泛使用 RTTI。

借助新的 RTTI 功能,我们应该会看到更高级的框架和工具出现,类似于 .NET 可用的功能。与 RTTI 本身相比,这些框架将彻底改变您的开发。

【讨论】:

  • 所以,大多数人会间接使用使用它的东西。但大多数人不会直接使用它。就像大多数人不会编写组件一样。但是每个人都使用它们。
【解决方案3】:

D2010 的扩展 RTTI 很像 C# 的反射。它使您能够获取对象的任何字段,或检查其方法。这有各种潜在用途。例如,如果您可以读取对象的任何字段,那么您就可以编写可以与任何对象一起使用的序列化代码。并且检查方法并获得它们的名称和签名的能力使类更容易在脚本引擎中注册。

对我来说,这是扩展 RTTI 的主要优势:能够通过检查其成员来编写适用于任何类的代码,而不是一遍又一遍地编写相同代码的不同版本,为每个单独的类量身定制。

【讨论】:

  • 是的。本质上,框架所做的就是为您提供一种机制,一种抽象,您应该能够重用该机制或抽象。因此,许多答案中的框架概念与您的答案紧密相关。
【解决方案4】:

自 1.0 版以来,Delphi 中的 RTTI 一直很重要。经典 RTTI 功能包括类的“已发布”属性部分,它允许对象检查器和组件设计时功能工作。出于我的目的,我经常使用已发布的类属性来允许在运行时枚举这些属性。将我的对象中的内容存储到磁盘中,以保持持久性。

Delphi 2010 RTTI 极大地扩展了这个经典的 RTTI,以至于您认为 Delphi 甚至在 delphi 2010 之前都没有 RTTI 是可以原谅的。

我想说“新 RTTI”的 #1 最有用的应用程序(正如其他几个答案已经指出的那样)将出现在大师编写的框架中,即:

  1. 处理文件或数据库的持久性。数据库和配置或文档保存/加载框架和组件将在后台使用它。

  2. 处理各种酸洗/编组/编码/解码 有线格式,如 JSON、XML、EDI 和其他格式。

  3. 其他人 (JUnit) 提到了单元测试,但我认为也许相同的框架对于调试和错误报告工具可能非常方便。给定一个在堆栈上作为参数传递的对象,为什么不提供错误报告来转储传递给失败函数的所有数据,而不仅仅是函数列表?

如您所见,一些有创意的人可能会想到更多的用途。你可以说,虽然它没有为 .NET 反射带来奇偶性(另一个答案对此进行了更多说明),但它确实为其他强类型静态带来了许多“动态语言”特性(想想 Perl、Python、JavaScript) -Delphi 类型的系统世界。

【讨论】:

  • 所有这些都在新的所有唱歌所有跳舞的RTTI之前已经存在。我什至自己写了一个持久化框架和单元测试框架,没有借助超级重复的 RTTI。
  • 请您给我写一个使用旧 RTTI 的堆栈转储例程,该例程将转储所有类引用及其所有未发布的属性,好吗?漂亮,漂亮吗?
  • 为什么?这只是懒惰的调试。堆栈转储只需要足够的信息来定位问题。然后,您需要创建一个可重现的测试用例来调查问题。然后,您可以在 DEBUGGER 中检查您需要的代码的所有方面,而不必为您的发布代码带来应该永远不需要的诊断包袱。这将是一个案例,是的,也许“新 RTTI”使成为可能,但不应该是必要的。
  • 很好,你不喜欢它,也不需要它。我觉得它非常有用。
【解决方案5】:

就我个人而言,扩展 RTTI 提供了从方法指针检索调用约定的可能性。但是,目前,该代码处于条件指令下,因为我对它不满意。

(欢迎对基本 RTTI 的工作提出批评和建议)

【讨论】:

    【解决方案6】:

    查找TMS Aurelius,您会发现RTTI 属性在创建ORM 数据库框架和XML 序列化为纯对象方面非常有用,反之亦然。

    【讨论】:

      【解决方案7】:

      你应该关心,因为他们把它放在盒子上。显然他们认为有些人会关心。

      您是否真正使用它完全取决于您的项目的性质。由于您以前没有它并且不明白为什么现在拥有它是一个好处,这会向我暗示您没有用它。然后由您决定是否花时间进一步研究该主题以发现您是否能够找到它的用途。

      这是否是您在项目中最有效地利用时间,这也是只有您自己知道的事情。

      【讨论】:

      • 您的回答通常很有帮助。这个不是。
      • 发帖人让我们告诉他RTTI对他有什么用处。 没有人可以在不知道他的项目和需求以及海报本身的情况下回答这个问题。
      • 同意以上观点。您的评论没有帮助。
      • 您当然有权发表自己的意见。您提供的新 RTTI“使之成为可能”的 3 个示例都存在于“新 RTTI”之前。如果您正在回答一个问题,即“这件事使以前不可能的事情成为可能(即使用以前的 RTTI 和语言的功能)”,那么在没有需要“新的 RTTI”。我想我们必须承认,也许您根本不知道那些以前的现有功能。
      • 如果您的语气不那么消极,那么您的回复在传达您的意图方面的效果会较差。
      猜你喜欢
      • 1970-01-01
      • 2014-01-05
      • 1970-01-01
      • 2010-09-25
      • 2011-02-10
      • 1970-01-01
      • 1970-01-01
      • 2012-02-15
      • 2019-05-27
      相关资源
      最近更新 更多