Интерфейс с использованием подкласса как типа поля - PullRequest
1 голос
/ 08 мая 2020

Мне нужно указать конкретный c подкласс AIState интерфейса IState в другом подклассе AIContext, который использует тот же класс интерфейса, что и общий c тип в IState ... У меня проблемы с правильным синтаксическим анализом.

Я создаю Statemachine, который работает на основе контекста: означает, что каждое состояние + SM существует один раз, и тот, кто использует SM, просто вызывает функцию в классе с контекстом в качестве параметра. Контекстные ссылки

У меня есть интерфейсы

public interface IStateContext
{
   IState<IStateContext> CurrentState { get; }
}

Interface IState <T> where T:IStateContext {
  Execute(T context);
}

Я реализую свое состояние для AI Behavior с помощью цвета для визуализации:

public class AIState : IState <AIContext> {
   Color stateColor;
   Execute(AIState) { //behavior}
}

ХОРОШО. Теперь вопрос начинается. Я могу создать только AIContext следующим образом:

[System.Serializable]
public class AIContext : IStateContext 
{
    public AI ai;
    public Animator animator;
    public NavMeshAgent agent;

    private IState<IStateContext> activeState;
    public IState<IStateContext> ActiveState
    {
        get => activeState;
        set => activeState = value;
    }
}

Мне нужно, чтобы активное состояние было AIState, но оно просто не позволяет подклассам ... Я хочу иметь доступ к (AIContext ) context.ActiveState.color! Но пока это просто IState, у него нет информации «цвет».

Попытка и ошибка 1: Мне не удалось разобрать его. Это просто не позволяет мне.

Попробуй и ошибка 2: Я не могу использовать общий c тип внутри IStateContext, который является IState, потому что тогда это всего лишь oop объявления общего c типа .. ... AIState : IState<AIContext<AIState<AI .....>>>

Боюсь, это структурная проблема? Надеюсь, кто-нибудь это увидит.

Изменить: проблема не только в цвете, я, возможно, захочу реализовать другие переменные позже. Его разбор. Мой StateMAchine просто использует обобщения (IState -> Выполняет их с IStateContext). Я просто не вижу возможности сохранить текущее активное состояние в контексте.

IStateContext имеет IState CurrentState, где T: IStateContext, а в AIState мне нужен AIContext CurrentState. Я просто не могу его разобрать!

1 Ответ

1 голос
/ 08 мая 2020

Подход A

Если вы можете заставить любой класс, реализующий интерфейс IState, иметь StateColor, вы можете просто добавить свойство StateColor в ваш интерфейс.

public interface IState<T> where T : IStateContext
{
    Color StateColor { get; set; }
    void Execute(T context);
}

public class AIState : IState<AIContext>
{
    public Color StateColor { get; set; }
    public void Execute(AIContext context) { }
}

[Serializable]
public class AIContext : IStateContext
{
    private IState<IStateContext> activeState;
    public IState<IStateContext> ActiveState
    {
        get => activeState;
        set => activeState = value;
    }

    public IState<IStateContext> CurrentState => throw new NotImplementedException();
}

Это позволит вам получить доступ к StateColor вашего свойства AIContext s ActiveState:

var aiContext = new AIContext();
var stateColor = aiContext.ActiveState.StateColor;

Подход B

Если вы не хотите изменять интерфейс IState, другим вариантом может быть создание нового интерфейса, например IAIState, который реализует интерфейс IState.

public interface IAIState<T> : IState<T> where T : IStateContext
{
    Color StateColor { get; set; }
}

public interface IState<T> where T : IStateContext
{
    void Execute(T context);
}

Тогда вам нужно будет только изменить тип поля activeState и свойства ActiveState на IAIState ...

[Serializable]
public class AIContext : IStateContext
{
    private IAIState<IStateContext> activeState;
    public IAIState<IStateContext> ActiveState
    {
        get => activeState;
        set => activeState = value;
    }

    IState<IStateContext> IStateContext.CurrentState { get; }
}

... для доступа к StateColor из ActiveState как указано выше:

var aiContext = new AIContext();
var stateColor = aiContext.ActiveState.StateColor;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...