what is going wrong with this code:
INamed = interface
function GetName : String;
property Name : String read GetName;
end;
Person = class(TInterfacedObject, INamed)
strict private
name_ : String;
function GetName : String;
public
constructor Create(firstName : String); reintroduce;
property Name : String read GetName;
end;
// trivial Person implementation...
Printer<T : INamed> = class
ref : T;
procedure Print;
end;
Printer2 = class
ref : INamed;
procedure Print;
end;
procedure Printer<T>.Print;
begin
//WriteLn(ref.Name); // <-- this line gives access violation
WriteLn(ref.GetName); // <-- this is ok
end;
procedure Printer2.Print;
begin
WriteLn(ref.Name);
end;
//////////////////////////////////////////////////////////////
var
john : Person;
print : Printer<Person>;
print2 : Printer2;
begin
john := Person.Create('John');
print := Printer<Person>.Create;
print2 := Printer2.Create;
print.ref := john;
print2.ref := john;
print.Print;
print2.Print;
ReadLn;
end.
The Printer2 class works fine. The generic Printer works with the call to GetName but not using the property: Access violation ... read of address...
Edit Example more related to my real code
INamed = interface
function GetName : String;
property Name : String read GetName;
end;
Person = class(TInterfacedPersistent, INamed)
strict private
name_ : String;
function GetName : String; inline;
public
constructor Create(firstName : String); reintroduce;
property Name : String read GetName;
end;
NameCompare = class(TComparer<Person>)
function Compare(const l, r: Person): Integer; override;
end;
GenericNameCompare<T :INamed> = class(TComparer<T>)
function Compare(const l, r: T): Integer; override;
end;
{ Person }
constructor Person.Create(firstName: String);
begin
inherited Create;
name_ := firstName;
end;
function Person.GetName: String;
begin
Result := name_;
end;
{ NameCompare }
function NameCompare.Compare(const l, r: Person): Integer;
begin
Result := AnsiCompareText(l.Name, r.Name);
end;
{ GenericNameCompare<T> }
function GenericNameCompare<T>.Compare(const l, r: T): Integer;
begin
//Result := AnsiCompareText(l.Name, r.Name); // <-- access violation
Result := AnsiCompareText(l.GetName, r.GetName);
end;
var
list : TObjectList<Person>;
p : Person;
begin
try
list := TObjectList<Person>.Create;
list.Add(Person.Create('John'));
list.Add(Person.Create('Charly'));
list.Sort(GenericNameCompare<Person>.Create);
for p in list do
WriteLn(p.Name);
ReadLn;
except
on E: Exception do begin
Writeln(E.ClassName, ': ', E.Message);
ReadLn;
end;
end;
end.