Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#和图遍历的代表:如何提高代码的重用_C#_Oop_Graph_Delegates - Fatal编程技术网

C#和图遍历的代表:如何提高代码的重用

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 {

我正在做一个图形实现。 我的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
{
...
}
我希望避免使用相同方法的相同实现。唯一改变的是方法签名和调用方法的对象

有人有什么想法来改进代码的设计吗

编辑:


我可以将所有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
    ...
}