与我上次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;
(简化和删除错误检查)
答案 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;
这可能不是正确的答案,但我希望这有助于您找到解决方案。