C#和图遍历的代表:如何提高代码的重用
我正在做一个图形实现。 我的Graph类如下所示:C#和图遍历的代表:如何提高代码的重用,c#,oop,graph,delegates,C#,Oop,Graph,Delegates,我正在做一个图形实现。 我的Graph类如下所示: public class Graph<VERTEX_TYPE, EDGE_TYPE, IDENTIFIER_TYPE> where VERTEX_TYPE : Identifier<IDENTIFIER_TYPE> where EDGE_TYPE : Identifier<IDENTIFIER_TYPE> where IDENTIFIER_TYPE : IConvertible {
public class Graph<VERTEX_TYPE, EDGE_TYPE, IDENTIFIER_TYPE>
where VERTEX_TYPE : Identifier<IDENTIFIER_TYPE>
where EDGE_TYPE : Identifier<IDENTIFIER_TYPE>
where IDENTIFIER_TYPE : IConvertible
{
...
}
我希望避免使用相同方法的相同实现。唯一改变的是方法签名和调用方法的对象
有人有什么想法来改进代码的设计吗
编辑:
我可以将所有4个委托传递给一个函数,但在每次遍历过程中,我只会使用其中的一对,因此看起来不是很干净。首先,我强烈建议您更改类型参数的命名。惯例是先使用
T
前缀,然后使用pascalcated名称,例如TVertex
和TEdge
接下来,如果您发现自己需要几个相关的委托,那么听起来您确实需要一个包含多个方法的接口。如果您想使用lambda表达式来表示操作,则始终可以创建接口的no-op实现,以便只覆盖一个方法,甚至可以提供静态方法,从委托创建具体实现的实例
这基本上就是被动扩展对界面的作用,它工作得非常好。谢谢您的建议。实际上,我使用的是无操作实现。我希望编译器能优化这样的无操作方法调用,是吗?@Heisenbug:不,编译器不能优化它,因为它是对虚拟方法的调用。但你为什么在乎?你有证据证明这是一个瓶颈吗?没有,实际上没有证据。我之所以在乎,是因为我正计划在相当大的图上应用几种图遍历算法,所以我试图避免不必要的方法调用。@Heisenbug:听起来你需要做一些性能分析,但在你有证据证明这是个问题之前,不要对优雅的解决方案进行微优化:)谢谢你的回答。也谢谢你的深入报道。我正在读这本书,我开始喜欢上C。)
public class Vertex<VERTEX_TYPE,EDGE_TYPE,IDENTIFIER_TYPE>
where VERTEX_TYPE : Identifier<IDENTIFIER_TYPE>
where EDGE_TYPE : Identifier<IDENTIFIER_TYPE>
{
public VERTEX_TYPE Data{get;private set;}
....
}
public class Edge<EDGE_TYPE,VERTEX_TYPE,IDENTIFIER_TYPE>
where EDGE_TYPE : Identifier<IDENTIFIER_TYPE>
where VERTEX_TYPE : Identifier<IDENTIFIER_TYPE>
{
public EDGE_TYPE Data{get;private set;}
....
}
public class GraphVisitor<VERTEX_TYPE, EDGE_TYPE, IDENTIFIER_TYPE>
where VERTEX_TYPE : Identifier<IDENTIFIER_TYPE>
where EDGE_TYPE : Identifier<IDENTIFIER_TYPE>
where IDENTIFIER_TYPE : IConvertible
{
public delegate void VertexDataOperation(VERTEX_TYPE vertex);
public delegate void EdgeDataOperation(EDGE_TYPE vertex);
public delegate void VertexOperation(Vertex<VERTEX_TYPE,EDGE_TYPE,IDENTIFIER_TYPE> vertex);
public delegate void EdgeOperation(Edge<EDGE_TYPE,VERTEX_TYPE,IDENTIFIER_TYPE> vertex);
.....
}
public void BFS(VertexOperation op, EdgeOperation edgeOp)
{
...
Vertex<VERTEX_TYPE,EDGE_TYPE,IDENTIFIER_TYPE> currentVertex;
op(currentVertex);
foreach (Edge<EDGE_TYPE,VERTEX_TYPE,IDENTIFIER_TYPE> e in currentVertex.NeighBors())
{
edgeOp(e);
...
}
...
public void BFS(VertexDataOperation op, EdgeDataOperation edgeOp)
...
Vertex<VERTEX_TYPE,EDGE_TYPE,IDENTIFIER_TYPE> currentVertex;
op(currentVertex.Data); //method differs only here
foreach (Edge<EDGE_TYPE,VERTEX_TYPE,IDENTIFIER_TYPE> e in currentVertex.NeighBors())
{
edgeOp(e.Data);//method differs only here
...
}