Круговая зависимость с генериками - PullRequest
4 голосов
/ 21 мая 2010

Я определил следующий интерфейс:

public interface IStateSpace<State, Action>
where State : IState
where Action : IAction<State, Action> // <-- this is the line that bothers me
{
    void SetValueAt(State state, Action action);
    Action GetValueAt(State state);
}

По сути, интерфейс IStateSpace должен быть чем-то похожим на шахматную доску, и в каждой позиции шахматной доски у вас есть набор возможных движений. Эти движения здесь называются IAction с. Я определил этот интерфейс таким образом, чтобы я мог приспособиться к различным реализациям: затем я могу определить конкретные классы, которые реализуют 2D-матрицу, 3D-матрицу, графики и т. Д.

public interface IAction<State, Action> {
    IStateSpace<State, Action> StateSpace { get; }
}

IAction, будет двигаться вверх (то есть, если в (2, 2) перейти к (2, 1)), двигаться вниз и т. Д. Теперь я хочу, чтобы каждое действие имело доступ к StateSpace, чтобы оно могло выполнять некоторую логику проверки. Это правильная реализация? Или это плохой случай круговой зависимости? Если да, как выполнить «то же самое» по-другому?

Спасибо

1 Ответ

2 голосов
/ 21 мая 2010

Указанная вами круговая ссылка не является проблемой. Чтобы ваш код компилировался, вам необходимо изменить определение интерфейса IAction:

public interface IAction<State, Action>
    where State : IState
    where Action: IAction<State, Action>
{
    IStateSpace<State, Action> StateSpace { get; }
}

Как это для циклической ссылки :) Обычно компилятор обрабатывает их с помощью заполнителей. В случае ограничений общего типа это, вероятно, даже не требуется. Одно небольшое замечание: если вы определите циклическую ссылку между классами, которые не находятся в одной сборке, это станет проблемой.

...