Reputation: 16612
related to my last question, I now have the following problem:
function TNodeFactory <T>.CreateNode (ID : Integer) : INodeInterface <T>;
var
NodeClass : TClass;
begin
NodeClass := FindRegisteredClass (ID);
Result := NodeClass.Create;
end;
This yields a compiler error:
E2010 Incompatible Types: 'INodeInterface<TNodeFactory<T>.T>' and 'TObject'
A cast does not work too.
What am I missing here?
EDIT: Current implementation
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;
(simplified and removed error checks)
Upvotes: 2
Views: 3084
Reputation: 58441
The problem is NodeClass being a TClass. If you create NodeClass it will be a mere TObject, not a INodeInterface.
You could try
Result := TInterfacedObject(RegisteredType.NodeClass).Create as INodeInterface
or change RegisterNodeType to
type
TInterfacedObjectClass = class of TInterfacedObject;
...
procedure RegisteredNodeType...(ID: Integer; NodeClass : TInterfacedObjectClass);
and return
Result := RegisteredType.NodeClass.Create as INodeInterface.
Upvotes: 3
Reputation: 10808
In Delphi an Interface is not an Object. And the Interface-Pointer is not an Objectpointer, that's why you can't cast them. You need to use QueryInterface and query for the Interface.
function QueryInterface(var IID: TGUID; out Obj: Type):HRESULT
if HRESULT is S_OK, then obj contains a reference to the queried interface.
Unfortunatly Delphi (Win32) handles Interfaces different to .NET/Java.
Upvotes: 2
Reputation: 4087
You need to use the Supports() function to extract an interface reference from an object. You'll find it in SysUtils.
There are several overloaded versions, you want the three parameter version with which the third "out" parameter brings you back your interface reference.
Upvotes: 2
Reputation: 33232
Let me start my answer with this discloser: I'm not that familiar with the use of templates in Delphi.
You are getting the compiler error because you try to return NodeClass which is defined as an instance of TClass. However, the function expects you to return an instance of a class that implements INodeInterface. You might be able to solve this problem with something like this
Result := INodeInterface(NodeClass.Create);
or
function TNodeFactory <T>.CreateNode (ID : Integer) : INodeInterface <T>;
var
NodeClass : TClass;
NodeInterface: INodeInterface;
begin
NodeClass := FindRegisteredClass (ID);
NodeInterface:= NodeClass.Create;
Result := NodeInterface;
end;
This might not be the right answer but I hope this helps lead you to the solution.
Upvotes: 0