已经讨论了带有可选数据字段的顶点类SKIP GENERIC PARAMETER ON DEMAND;对我来说最好的解决方案是这样的:
type
TVertex = class
public
Name: String;
OutputAttributes: TVertexOutputAttributes;
Marker: Boolean;
end;
type
TVertex<T> = class(TVertex)
public
Data: T; // User-defined data attribute
end;
现在写连接图类时,我想出了另一个问题:
TGraph = Class
private
Vertices: TObjectList<TVertex>;
....
function addVertex(u: TVertex): Integer;
function removeVertex(u: TVertex): TVertex;
end;
所有函数现在请求我的顶点类Tvertex的非泛型版本。扩展我的Graph类以使用两个顶点类定义(通用Tvertex和非通用一个TVertex)的最佳方法是什么?我尝试了以下代码但没有成功。
// a generic class working with 2 Tvertex class definitions ...
// this code does npot work :-(
TGraph<MyVertexType> = Class
private
Vertices: TObjectList<MyVertexType>;
....
function addVertex(u: MyVertexType): Integer;
function removeVertex(u: MyVertexType): MyVertexType;
end;
答案 0 :(得分:1)
您当前的代码无法编译,因为您使用的TObjectList<T>
要求T
成为一个类。没有强制执行的约束。所以你可以添加那个约束:
type
TGraph<MyVertexType: class> = class
FVertices: TObjectList<MyVertexType>;
...
end;
我确实想知道你是否已经完全考虑了顶点的终身所有权。使用TObjectList<T>
意味着您希望列表拥有对象并在从列表中删除它们时将其销毁。在这种情况下
function removeVertex(u: MyVertexType): MyVertexType;
没有意义。
请注意,上面的定义不允许图表类知道MyVertexType
的功能,而不仅仅是它是一个类。所以也许你应该将MyVertexType
限制为一个顶点:
type
TGraph<MyVertexType: TVertex> = class
...
end;
这将允许图形容器在其成员上调用顶点方法。
答案 1 :(得分:-1)
type
TVertex = class
public
Name: String;
OutputAttributes: TVertexOutputAttributes;
Marker: Boolean;
end;
TIntVertex = class(TVertex)
public
Data: Integer;
end;
TSomethingElseVertex = class(TVertex)
public
Data: TSomethingElse;
end;
TGraph = class(TObjectList<TVertex>)
// any additional methods
end;
...
var
Graph: TGraph;
Vertex: TVertex;
...
Vertex := TIntVertex.Create;
Graph.Add(Vertex);
Vertex := Graph.Last;
if (Vertex is TIntVertex) then
(Vertex as TIntVertex).Data := 42;