2016-02-23 15 views
13

Muszę zrobić wykres i chcę krawędzie i wierzchołki być rodzajowy typuPętla typu rodzajowego w C#

public interface IVertex<TVertex, TEdge> 
     where TVertex : IVertex<?> 
     where TEdge : IEdge<?> 
{ 
    bool AddEdge(TEdge e); 
    TEdge FindEdge(TVertex v); 
} 

public interface IEdge<TVertex> where TVertex : IVertex<?> 
{ 
    TVertex From { get; } 
} 

Ale krawędź wymagany typ wierzchołka i vertex wymagany typ krawędzi Co powinienem zrobić?

+0

'TEdge FindEdge (TVertex v);' co robi ta metoda? –

+0

Naprawdę chciałbym, aby ktoś dał obejście tego problemu jako tworzenie nietypowego 'IVertex' nad generycznym' IVertex 'lub dodanie' TItem' do 'IVertex ' ogólne parametry są jedynymi rozwiązaniami, jakie kiedykolwiek miałem spełnione do tej pory. – bashis

+0

Myślę, że to pytanie wymaga wyjaśnienia, dlaczego chcesz generycznych parametrów typu. Podaj przykład, w którym usunięcie wszystkich 'TVertex'ów i' TEdge's i zastąpienie ich '' IVertex' i 'IEdge' (na sygnaturach metod/właściwości) nie byłoby wystarczające, więc rozumiemy, co próbujesz osiągnąć –

Odpowiedz

6

Myślę, że robisz to bardziej skomplikowanym niż to konieczne.
Czy coś takiego działa?

public interface IVertex<T> 
{ 
    bool AddEdge(IEdge<T> e); 
    IEdge<T> FindEdge(IVertex<T> v); 
} 

public interface IEdge<T> 
{ 
    IVertex<T> From { get; } 
} 
+0

Co reprezentuje Ts? –

+0

@ BenAaronson [Ogólne parametry typów] (https://msdn.microsoft.com/en-us/library/0zk36dx2.aspx) – stuartd

+1

@stuartd Er, prawda, ale co konkretnie te parametry typu reprezentują w tym przypadku? W pytaniu są dwa typy: "TVertex" i "TEdge", które są odpowiednio ograniczone do implementacji 'IVertex' i' IEdge'. W tym przypadku 'T' wydaje się być całkowicie niezwiązanym typem. –

2

Wygląda na to, że chcesz krawędź i vertex przechowuje pewną wartość. Jeśli chcesz mieć TV wartości wierzchołki i krawędzie mają TE wartości można zrobić coś takiego:

public interface IVertex<TV, TE> 
{ 
    TV Value { get; } 
    bool AddEdge(IEdge<TV, TE> e); 
    IEdge<TV, TE> FindEdge(IVertex<TV, TE> v); 
} 

public interface IEdge<TV, TE> 
{ 
    TE Value { get; } 
    IVertex<TV, TE> From { get; } 
} 
2

Problemem jest to, że stworzyliśmy rekurencyjną definicję ze swoimi ograniczeniami typu. Mówisz, że IVertex<A> gdzie A musi być IVertex<B>, gdzie B musi być IVertex<C>, itp. ... W pewnym momencie musisz określić faktycznie określić typ lub interfejs jako parametr ogólny. Zaproponowano już kilka dobrych rozwiązań. Tutaj jest inny, jeśli potrzebujesz więcej opcji ...

Możesz wprowadzić inny typ lub interfejs (nietypowy), aby przerwać definicję rekursywną.

public interface IVertex<TVertex, TEdge> 
     where TVertex : IVertex 
     where TEdge : IEdge 
{ 
    bool AddEdge(TEdge e); 
    TEdge FindEdge(TVertex v); 
} 

public interface IEdge<TVertex> where TVertex : IVertex 
{ 
    TVertex From { get; } 
} 
2

Chociaż to spierać, czy to rzeczywiście dobry pomysł, nie ma nic Kompilator myśli o takich „krążącego” definicji:

interface IVertex<TVertex, TEdge> where TVertex : IVertex<TVertex,TEdge> 
            where TEdge : IEdge<TVertex,TEdge> 
{ 

} 

interface IEdge<TVertex, TEdge> where TVertex : IVertex<TVertex, TEdge> 
           where TEdge : IEdge<TVertex, TEdge> 
{ 

} 

Następnie można napisać na przykład:

class FooVertex : IVertex<FooVertex,BarEdge> 
{ 

} 

class BarEdge : IEdge<FooVertex,BarEdge> 
{ 

} 
Powiązane problemy