Delphi 如何确定接口的实现对象的类型

Delphi 如何确定接口的实现对象的类型,delphi,delphi-2009,typechecking,dunit,Delphi,Delphi 2009,Typechecking,Dunit,我试图为一个简单的工厂类编写一个单元测试,该工厂类创建几个可能的实现对象之一,并将其作为接口引用返回 DUnit有一个内置的过程,CheckIs(AObject:TObject;AClass:TClass;msg:string),如果对象的类类型与预期的不匹配,那么基于它的名称和它接受的参数,测试应该失败。唯一的问题是它需要对象引用而不是接口引用 因此,我尝试使用CheckTrue并在测试主体中执行比较,但我对Delphi的类型检查支持不像对C#的那么熟悉 我知道is操作符是不可能的,因为它只适

我试图为一个简单的工厂类编写一个单元测试,该工厂类创建几个可能的实现对象之一,并将其作为接口引用返回

DUnit有一个内置的过程,
CheckIs(AObject:TObject;AClass:TClass;msg:string)
,如果对象的类类型与预期的不匹配,那么基于它的名称和它接受的参数,测试应该失败。唯一的问题是它需要对象引用而不是接口引用

因此,我尝试使用
CheckTrue
并在测试主体中执行比较,但我对Delphi的类型检查支持不像对C#的那么熟悉

我知道
is
操作符是不可能的,因为它只适用于对象引用

CheckTrue(LMyInterfaceReference {comparison here} TMyClass);
有什么建议吗


顺便说一句,我使用的是Delphi 2009,因此我无法访问2010+中添加的新RTTI支持。

我想知道为什么您必须测试此功能。。。也许你真的不必

但如果必须了解接口的底层对象,则有两种选择:

  • 向接口添加一个方法,该方法返回底层对象,即一个TObject,并通过返回self在每个类中实现
  • 例如,使用此例程进行一些黑客攻击

如果您不喜欢黑客,也不想升级到Delphi 2010+,您可以使用如下界面:

IImplementingObjectInterface = interface
  function GetImplementingObject: TObject;
end;
确保您的对象也实现了这个接口,并使用它来提取实现对象。如果您需要为许多对象执行此操作,您可以定义自己的
TInterfacedObject
派生,该派生已经实现了此操作,因此您可以简单地更改继承并完成此操作。

(Embarcadero Delphi主要编译工程师之一)本周写了一篇不错的文章

它回答了你的问题

有趣的是,他写了一篇文章

从Delphi2010开始,您可以使用
is
检查或
as
转换从接口引用返回到对象引用

CheckTrue(LMyInterfaceReference {comparison here} TMyClass);

--jeroen

Delphi 2010允许您执行
Obj:=IUnknown as TObject
因为您使用的是Delphi 2009,所以您需要Barry Kelly的,最近在Stack Overflow上发布的!不发布作为回答,因为这会感觉像从巴里那里偷走代表@代码优雅,巴里的黑客+一个可选的IFEDF当你升级你的德尔福版本看起来是一个不错的交易。黑客在Delphi 2009上工作,如果升级,您将获得开箱即用的功能(可能是相同的代码),检查是否实现了spcific接口不是更糟糕吗?我猜OP正在进行单元测试,并希望检查实现对象是否如预期的那样。如果预期一个类具有特定的行为,为什么不测试它?您将类型代码(字符串、枚举等)传递给工厂,并期望它为您提供所请求类型的相应实例。如果它返回的是nil或错误类型的实例,那么您就有一个bug.codeEngl雅,如果您返回的是一个接口,那么请检查该接口是否符合预期。If不应该与底层对象的类型无关,甚至与是否存在底层对象无关。只要接口按预期的方式运行,为什么类很重要?如果精确的类类型很重要,那么返回类,而不是接口。@Rob我正在测试工厂是否按照其假设的方式运行。接口的使用者不知道或不关心接口的实现。这取决于工厂确保创建正确的实现。这就是我正在测试的。工厂的工作是生产实现特定接口的产品。如果工厂给了你一些东西,而你调用的方法做了它们应该做的,那么工厂已经完成了它的工作。你在错误的水平测试,错误的水平?给我看一个不需要测试的类,我给你看一个根本不需要的类。你只需要测试你想工作的东西肯特·贝克这一次让我大喊大叫。