【问题标题】:Is it possible to determine if two objects both implement a common interface which is not specified at compile time?是否可以确定两个对象是否都实现了在编译时未指定的公共接口?
【发布时间】:2018-11-17 18:44:18
【问题描述】:

给定 Object1 和 Object2,是否有任何技术可以确定它们是否都实现了一个公共接口?如果接口在编译时已知(使用 typeof ... 是 [已知接口]),则没有问题,但是如果在编译时未指定接口呢?

具体用例是实现一个强类型的集合对象。如果它与 Object1 共享一个公共接口,我只想添加 Object2。 Typename 不起作用,因为它返回基础对象类型,并且我可能有两个不同的对象,每个对象都实现 ISomeInterface 但在不同的基础类上。

可以找到一个不太有效的示例here(因为它依赖于 typename 但不允许进行接口比较)

具体来说,扩展 IsTypeSafe 函数找到了 here on CodeReview,但经过调整后,如果对象支持所有先前添加的项目共有的接口,则可以将其添加到列表中。

具体问题:有没有办法确定两个对象是否都实现了一个在编译时未指定的通用接口?

【问题讨论】:

  • FWIW 如果我今天要编写该代码,我可能会更好地将 VarType 枚举用于非对象类型。

标签: vba collections interface strong-typing implements


【解决方案1】:

我对您的“编译时未指定”措辞感到非常困惑,但您的问题的症结在于:

如果一个对象支持所有先前添加的项目通用的接口,则可以将其添加到列表中。

换句话说,您是在问是否有办法在 VBA 中执行此操作(VBA/C# 的伪混搭):

isOk = item.Type.Interfaces.Any(i => other.Type.Interfaces.Contains(i))

为了能够检查对象变量的已实现接口,您需要能够在运行时检查其类型。这种能力叫做“反射”……VBA 做不到。

Rubberduck(免责声明:我管理这个 OSS VBIDE 插件项目)有一个 COM API,它最终可能会完全支持它(它是开源的,实现它 - 我们很高兴接受拉取请求! ),但是为了发挥它的魔力,它需要从字面上解析和解析整个项目及其所有引用,这意味着将反射用于您想要使用它的目的,这将是一个大量性能下降。

VBA 中的“类型安全”List 类基本上是烟雾弹。对不起!

【讨论】:

  • 感谢@Matheiu Guidon。看起来我之前的评论被吃掉了:(....但是你的伪伪代码是正确的。因为我将我的“通用”类型安全集合包装在一个特定于类型的包装器(例如 ICollectionOfISomething)中无论如何,所有类型转换都在一个地方我可以将类型检查放在那里(我在编译时知道特定的接口 - 抱歉我的措辞混乱)。听起来反射路径绝对不是要走的路! :) 再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-22
  • 2015-11-03
  • 2022-01-22
  • 1970-01-01
  • 2021-10-01
  • 2010-11-09
相关资源
最近更新 更多