Angenommen, ich verwende eine external package for storing graphs. Ein BidirectionalGraph nimmt zwei Vorlagen: eine Ecke und einen Randtyp:Erlaube, dass Vorlagen abgeleitet werden
var graph = new BidirectionalGraph<Vertex, Edge<Vertex>>();
Leider ist dieses Diagramm Paket nicht zulässt, dass, um die Kanten zu bekommen strahl in eine Ecke in einer einzigen Zeile. Stattdessen müssen Sie eine IEnumerable
angeben, die mit den Ergebnissen ausgefüllt wird. Dies kann einen guten Codierungsrhythmus stören, indem Tasks wie "Schleife durch alle Knoten, die Nachfolger des Vertex x
sind, viel zu viel Code benötigen.
Ich wollte von .NET-Erweiterungen verwenden, um eine einzeilige Lösung der Graph Klasse hinzuzufügen:
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;
}
}
Aber wenn ich graph.IncomingEdges(vertex)
nennen, aus irgendeinem Grunde C# (.NET Version 4.5) kann nicht geschlossen werden die Template-Argumente, also muss ich sagen:
graph.IncomingEdges<GraphThatInheritsFromBidirectionalGraph<VertexType,EdgeType>,VertexType,EdgeType>(vertex)
. Nicht wirklich eine große Verbesserung.
Zuerst, warum können die Schablonentypen nicht geschätzt werden? Ich habe das Gefühl, dass es mit Vererbung zu tun hat, aber verstehe nicht. Ich bin es gewohnt, C++ zu verwenden, und aus irgendeinem Grund glaube ich, dass gcc die Vorlagentypen ableiten könnte.
Zweite wenn diese nicht verhindert werden kann, ist die richtige Design-Wahl eine Grafik-Klasse für den tatsächlichen Gebrauch zu machen, die von BidirectionalGraph erbt? Es scheint eine Verschwendung zu sein, die Konstruktoren neu schreiben zu müssen, aber ich bin mir sicher, Sie würden zustimmen, dass das Aufrufen der Methode mit expliziten Vorlagentypen unelegant ist.
EDIT:
Strangely die äquivalente Spezifikation (unten) tut erlauben automatische Inferenz von Templat-Typen. Also, obwohl es mein anfängliches Problem löst (das Hinzufügen dieser Funktionalität zum Graphen), würde ich immer noch gerne verstehen.
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;
}
}
Was ist der Compilerfehler? Ich versuche, dies zu reproduzieren, ohne die Grafik Bibliothek herunterladen .. aber bisher versage ich :( –
@SimonWithehead Es heißt "Fehler 1 'MyDerivedGraph' enthält keine Definition für 'IncomingEdges' und keine Erweiterungsmethode 'IncomingEdges 'könnte ein erstes Argument vom Typ' MyDerivedGraph 'gefunden werden (fehlt eine using-Direktive oder eine Assembly-Referenz?) ", aber wenn ich die Template-Typen manuell spezifiziere, kompiliert und läuft es gut. (EDIT: Resharper schlägt vor, < > versuche mir zu helfen, Templates manuell einzufügen – user