RjK
RjK

Reputation: 61

Problem with generics and interfaces and inheritance

The following example is giving me this error:
[DCC Error] Unit2.pas(54): E2010 Incompatible types: 'IBar' and 'Unit2.TFoo<Unit2.IBar>'

I think the problem is somewhere around the Self.Create Because after many tries to get it compiled I accidentally entered FFoo := TBar(Self).Create; and it compiled and worked.

I'm using Delphi XE

IFoo = interface
end;

TFoo<T: IInterface> = class(TInterfacedObject, IFoo)
private class var
  FFoo: T;
public class
  function Instance: T;
end;

IBar = interface(IFoo)
end;

TBar = class(TFoo<IBar>, IBar)
end;

class function TFoo<T>.Instance: T;
begin
  if not Assigned(FFoo) then
  begin
    FFoo := Self.Create;
  end;
  Result := FFoo;
end;

Upvotes: 6

Views: 1110

Answers (2)

TridenT
TridenT

Reputation: 4909

The problem is in this line with the TBar declaration:

FFoo := Self.Create;

To understand, let's explain the types behind the code [noted like this]:

FFoo:[IBar] := Self:[TFoo(IBar)].Create():[TFoo<IBar>]

So, tu summarize, we have : [IBar] := [TFoo<IBar>]
Are these types compatible ?
A [TFoo] only implements IFoo interface, no IBar as it is stated in your code

TFoo<T: IInterface> = class(TInterfacedObject, IFoo)

This is the compilation error !
UPDATE : Solution 1
To fix the issue : change the TBar declaration

TBar = class(TFoo<IFoo>, IBar)
end;

UPDATE : Solution 2
Replace the FFoo := Self.Create by

FFoo := Self.Create.Instance;

and so it works !

Upvotes: 3

Stefan Glienke
Stefan Glienke

Reputation: 21713

Your TFoo does not implement T as interface. That's why FFoo and an instance of TFoo is not compatible. If you want to assign an instance of TFoo to FFoo you need to hardcast it.

Upvotes: 1

Related Questions