这里使用Delphi的通用编程功能来定义Vertex类和图形类:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
System.Math, System.Generics.Collections,
System.Generics.Defaults, Vcl.StdCtrls;
type
tvertex = class(TObject)
name: string;
function markme: tvertex;
function Compare(const v: TVertex): Integer;
constructor create;
destructor free;
end;
tvertex<T> = class(tvertex)
Userdata: T;
end;
TGraph <T : class > = class (Tobject)
vertexlist : TObjectList<T>;
procedure CompareLists(
var _V1: TObjectList<T>;
var _V2: TObjectList<T>);
end;
TForm1 = class(TForm)
Edit1: TEdit;
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
// helper function
function createVertexComparer(): IComparer <TVertex >;
implementation
// helper functions
function createVertexComparer(): IComparer<TVertex>;
begin
Result := TDelegatedComparer<TVertex>.Create(
function(const Left, Right: TVertex): Integer
begin
Result := Left.Compare(Right);
end);
end;
{$R *.dfm}
{ tvertex }
function tvertex.Compare(const v: TVertex): Integer;
begin
// ...
end;
constructor tvertex.create;
begin
// ...
end;
destructor tvertex.free;
begin
// ...
end;
function tvertex.markme: tvertex;
begin
// ...
end;
procedure TGraph<T>.CompareLists(
var _V1: TObjectList<T>;
var _V2: TObjectList<T>);
begin
_V1 := TObjectList<T>.Create(createVertexComparer(), False); /// line which does not compile ....
end;
end.
如何修改他愿意接受TVertex
和TVertex<T>
类类型作为参数的代码....
答案 0 :(得分:2)
我想说你遇到的主要问题是你声明了这样的图形类:
type
TGraph<T: class>
...
end;
这意味着编译器将接受任何类T
。因此,图表类对T
一无所知,除此之外它是一个类。
很难确定,但我认为你打算T
成为一个顶点。所以你需要适当地约束图类。
type
TGraph<T: TVertex>
...
end;
然后你有这个功能的另一个问题:
function createVertexComparer(): IComparer<TVertex>;
您将结果传递给
TObjectList<T>.Create
但是这需要IComparer<T>
类型的参数,而您提供的是IComparer<TVertex>
。这是编译器报告的类型不匹配。
您需要将createVertexComparer
作为TGraph<T>
的方法,以便它可以是通用的。它的实施将是:
function TGraph<T>.createVertexComparer(): IComparer<T>;
begin
Result := TDelegatedComparer<T>.Create(
function(const Left, Right: T): Integer
begin
Result := Left.Compare(Right);
end);
end;
另外,请注意
destructor free;
等待发生的灾难。你必须使用
destructor Destroy; override;
事实上,你的其余代码让我很烦恼。例如:
procedure TGraph<T>.CompareLists(var _V1, _V2: TObjectList<T>);
begin
_V1 := TObjectList<T>.Create(createVertexComparer(), False);
end;
方法的名称与它的名称不匹配。它只返回一个值,为什么有两个var
参数?在查看这样的代码时很难辨别意图。