Подтвердить что ты не робот

Циклический тип типа С#

Мне нужно сделать график, и я хочу, чтобы ребра и вершины были типичными типами

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; }
}

Но для ребра требуется тип вершины, а для вершины требуется тип ребра Что мне делать?

4b9b3361

Ответ 1

Я думаю, что вы делаете это более сложным, чем это должно быть. Будет что-то вроде этой работы?

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

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

Ответ 2

Похоже, вы хотите, чтобы края и вершины сохраняли некоторую ценность. Если вы хотите, чтобы вершины имели значения TV, а ребра имели значения TE, вы можете сделать что-то вроде этого:

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; }
}

Ответ 3

Проблема заключается в том, что вы создали рекурсивное определение с ограничениями типа. Вы говорите, что IVertex<A> где A должно быть IVertex<B>, где B должно быть IVertex<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; }
}

Ответ 4

Пока он спорит о том, действительно ли это хорошая идея, нет ничего компилятора в отношении таких "циклических" определений:

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>
{

}

Затем вы можете написать, например:

class FooVertex : IVertex<FooVertex,BarEdge>
{

}

class BarEdge : IEdge<FooVertex,BarEdge>
{

}