2009-08-06 86 views
2

與我的最後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

結點類別是TClass。如果您創建NodeClass,它將僅僅是一個TObject,而不是一個INodeInterface。你將不得不向我們展示你的RegisterClass和FindRegisteredClass的實現。 – 2009-08-06 07:48:20

+0

添加實現到我的問題 – jpfollenius 2009-08-06 07:59:24

+1

您可以嘗試*結果:= TInterfacedObject(RegisteredType.NodeClass)。創建爲INodeInterface * – 2009-08-06 08:04:41

回答

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. 
0

讓我開始我的回答與此披露:我不是那個熟悉德爾福使用模板。

您正在收到編譯器錯誤,因爲您嘗試返回定義爲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; 

這可能不是正確的答案,但我希望這可以幫助你引向解決方案。

+0

正如我在問題中所說的:「演員陣容不能工作」。而第二個版本是恕我直言,只是第一個更長的版本。不管怎麼說,還是要謝謝你! – jpfollenius 2009-08-06 08:03:15

2

您需要使用Supports()函數從對象中提取接口引用。 你會在SysUtils中找到它。

有幾個重載版本,您需要三個參數版本,第三個「out」參數使您返回接口引用。

+0

這種方法從哪裏來?無法在TObject或Delphi幫助中找到它... – jpfollenius 2009-08-06 08:05:12

2

在Delphi中,接口不是對象。 Interface-Pointer不是一個Objectpointer,這就是爲什麼你不能施放它們的原因。您需要使用QueryInterface並查詢接口。

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

如果HRESULT是S_OK,則obj包含對查詢接口的引用。

不幸Delphi(Win32)處理與.NET/Java不同的接口。

+0

@Smasher:如果您查看Supports()的代碼,您會看到它調用QueryInterface(),因此您可以使用任何一個。 – LachlanG 2009-08-06 08:23:18

+0

+1沒有嘗試過,因爲列文的解決方案適合我。但是,謝謝! – jpfollenius 2009-08-06 08:41:13