从TObject转换为接口类型

时间:2009-08-06 07:31:40

标签: delphi oop delphi-2009 factory-pattern

与我上次question相关,我现在遇到以下问题:

function TNodeFactory <T>.CreateNode (ID : Integer) : INodeInterface <T>;
var
  NodeClass : TClass;
begin
  NodeClass := FindRegisteredClass (ID);
  Result := NodeClass.Create;      
end;

这会产生编译器错误:

E2010 Incompatible Types: 'INodeInterface<TNodeFactory<T>.T>' and 'TObject'

演员阵容也不起作用。

我在这里缺少什么?

编辑:当前实施

TNodeFactory <T> = class
private
  type
    TRegisteredNodeType = record
      ID : Integer;
      NodeClass : TClass;
    end;
private
  FNodeTypeList : TList <TRegisteredNodeType>
public
  procedure RegisterNodeType (ID : Integer; NodeClass : TClass);
  function  CreateNode (ID : Integer) : INodeInterface <T>;
end;

procedure TNodeFactory <T>.RegisterNodeType (ID : Integer; NodeClass : TClass);
var
  RegisteredType : TRegisteredNodeType;
begin
  RegisteredType.ID := ID;
  RegisteredType.NodeClass := NodeClass;
  FNodeTypeList.Add (RegisteredType);
end;

function TNodeFactory <T>.CreateNode (ID : Integer);
var
  RegisteredType : TRegisteredNodeType;
begin
  for RegisteredType in FNodeTypeList do
    if (RegisteredType.ID = ID) then
      Exit (RegisteredType.NodeClass.Create);
  raise EInvalidNodeType.Create ('No node type with ID ' + IntToStr (ID) + ' registered');
end;

(简化和删除错误检查)

4 个答案:

答案 0 :(得分:3)

问题是NodeClass是一个TClass。如果你创建NodeClass,它将只是一个TObject,而不是一个INodeInterface。

你可以尝试

Result := TInterfacedObject(RegisteredType.NodeClass).Create as INodeInterface

或将RegisterNodeType更改为

type
  TInterfacedObjectClass = class of TInterfacedObject;   
...   
procedure RegisteredNodeType...(ID: Integer; NodeClass : TInterfacedObjectClass);

并返回

Result := RegisteredType.NodeClass.Create as INodeInterface. 

答案 1 :(得分:2)

您需要使用Supports()函数从对象中提取接口引用。 你会在SysUtils中找到它。

有几个重载版本,你需要三个参数版本,第三个“out”参数会带你回到你的界面参考。

答案 2 :(得分:2)

在Delphi中,接口不是对象。并且Interface-Pointer不是Objectpointer,这就是你无法投射它们的原因。您需要使用QueryInterface并查询接口。

function QueryInterface(var IID: TGUID; out Obj: Type):HRESULT

如果HRESULT是S_OK,则obj包含对查询接口的引用。

不幸的是,Delphi(Win32)处理与.NET / Java不同的接口。

答案 3 :(得分:0)

让我以这个披露者的方式开始我的答案:我不熟悉Delphi中模板的使用。

您收到编译器错误,因为您尝试返回定义为TClass实例的NodeClass。但是,该函数希望您返回实现INodeInterface的类的实例。你可以用这样的东西来解决这个问题

Result := INodeInterface(NodeClass.Create);     

function TNodeFactory <T>.CreateNode (ID : Integer) : INodeInterface <T>;
var
  NodeClass : TClass;
  NodeInterface: INodeInterface;
begin
  NodeClass := FindRegisteredClass (ID);
  NodeInterface:= NodeClass.Create;
  Result := NodeInterface;      
end;

这可能不是正确的答案,但我希望这有助于您找到解决方案。