1
votes

i few days a go someone asked me why this code gives a error. i tried to figure out but i couldnt, so i hope u guys help us.

first unit: where the classe is defined unit Unit1;

interface

type
  TSomeGeneric<T> = class
  private
    function getSelf: TSomeGeneric<T>;
  public
    property This : TSomeGeneric<T> read getSelf;
  end;

implementation

{ TSomeGeneric<T> }

function TSomeGeneric<T>.getSelf: TSomeGeneric<T>;
begin
  Result := Self;
end;

end.

unit2 : its makes a referente to the classe defined in unit 1 unit Unit2;

interface

uses
  Unit1;

type
  TSomeGeneric<T> = class(Unit1.TSomeGeneric<T>);

implementation

end.

frmmain: it uses unit2 is some point unit ufrmMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,

  Unit2;

type
  TfrmMain = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure SomeProcedure(ASG : TSomeGeneric<Integer>);
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

{ TfrmMain }

procedure TfrmMain.FormCreate(Sender: TObject);
var ASG : TSomeGeneric<Integer>;
begin
  ASG := TSomeGeneric<Integer>.Create();
  with ASG do
    try
      //make use os the class ...
      SomeProcedure(This); //error -> incompatible types
    finally
      Free();
    end;
end;

procedure TfrmMain.SomeProcedure(ASG: TSomeGeneric<Integer>);
begin
  //...
end;

end.

i have a suspicious that at this point TSomeGeneric = class(Unit1.TSomeGeneric) the TSomeGeneric is defined as another classe and not a reference, but i cant confirm that

1
Yes, it's certainly another class — a descendant of the Unit1 class by the same name. If you suspect that's the problem, why can't you confirm it? Just delete Unit2 and use Unit1 instead, and see whether the program compiles and works. Does it work if you call SomeProcedure(ASG) instead of SomeProcedure(This)?Rob Kennedy
yes it works when SomeProcedure(ASG) is used, but not when the property ASG.This is passed. Thats exactly where im lost, its becouse ASG.This is actually another class? the Unit.TSomeGeneric<T> and not Unit2.TSomeGeneric<T> that is expected in the procedure param?kabstergo

1 Answers

4
votes

The compiler makes it quite clear. The problematic line is this one:

  SomeProcedure(This);

The error is:

[dcc32 Error] E2010 Incompatible types: 'Unit2.TSomeGeneric' and 
'Unit1.TSomeGeneric'

That's because in that method call:

  • This is of type Unit1.TSomeGeneric<System.Integer> and
  • SomeProcedure expects a parameter of type Unit2.TSomeGeneric<System.Integer>.

And those are not the same type because you explicitly made them different.

type
  TSomeGeneric<T> = class(Unit1.TSomeGeneric<T>);

defines a new type and now you have two types that are not compatible.

You will simply have to remove Unit2. It serves no purpose other than to stop reasonable code compiling.