假设我正在使用外部包来存储图形。BidirectionalGraph 有两个模板:一个顶点和一个边类型:
var graph = new BidirectionalGraph<Vertex, Edge<Vertex>>();
不幸的是,此图形包不允许您将边缘辐射到单行中的顶点。相反,您必须提供一个IEnumerable
,它将填充结果。这可能会破坏良好的编码节奏,因为诸如“遍历所有顶点的后继顶点x
”之类的任务需要太多的代码。
我想使用 .NET 的扩展为图形类添加单行解决方案:
public static class GraphExtensions
{
public static IEnumerable<TEdge> IncomingEdges<TGraphSubtype, TVertex, TEdge>(this TGraphSubtype graph, TVertex n)
where TGraphSubtype : BidirectionalGraph<TVertex, TEdge>
where TEdge : IEdge<TVertex>
{
IEnumerable<TEdge> inputEdgesForVertex;
graph.TryGetInEdges(n, out inputEdgesForVertex);
return inputEdgesForVertex;
}
}
但是当我调用时graph.IncomingEdges(vertex)
,由于某种原因 C#(.NET 4.5 版)无法推断模板参数,所以我不得不说:
graph.IncomingEdges<GraphThatInheritsFromBidirectionalGraph<VertexType,EdgeType>,VertexType,EdgeType>(vertex)
. 真的不是很大的进步。
首先,为什么不能估计模板类型?我感觉它与继承有关,但不明白。我习惯使用 C++,出于某种原因觉得 gcc 可以推断模板类型。
其次,如果这无法避免,那么制作一个继承自 BidirectionalGraph 的图形类以供实际使用是正确的设计选择吗?必须重写构造函数似乎是一种浪费,但我相信您会同意使用显式模板类型调用该方法是不优雅的。
编辑:
奇怪的是,等效规范(如下)确实允许自动推断模板类型。所以,即使它解决了我最初的问题(将这个功能添加到图表中),我仍然很想了解。
public static class GraphExtensions
{
public static IEnumerable<TEdge> IncomingEdges<TVertex, TEdge>(this BidirectionalGraph<TVertex,TEdge> graph, TVertex n)
where TEdge : IEdge<TVertex>
{
IEnumerable<TEdge> inputEdgesForVertex;
graph.TryGetInEdges(n, out inputEdgesForVertex);
return inputEdgesForVertex;
}
}