C#存储泛型状态

C#存储泛型状态,c#,generics,fsm,C#,Generics,Fsm,“守门员”、“FieldPlayer”和“Team”类型的每个对象都将有一个状态机实例。问题是。。泛型不能是属性 我该怎么办?在阅读了更多的代码之后,这里不需要抽象类。您应该将状态转换为接口,例如:IState,并从中删除通用签名。然后,您的FSM对象中的属性都可以是public-IState-globalState等。如果您将State设置为普通接口,而不是泛型接口,并且让其Enter方法使用您的团队、守门员、球员等都实现的另一个接口(它甚至可以是空的),那么它应该可以工作 public cl

“守门员”、“FieldPlayer”和“Team”类型的每个对象都将有一个状态机实例。问题是。。泛型不能是属性


我该怎么办?

在阅读了更多的代码之后,这里不需要抽象类。您应该将状态转换为接口,例如:IState,并从中删除通用签名。然后,您的FSM对象中的属性都可以是public-IState-globalState等。

如果您将State设置为普通接口,而不是泛型接口,并且让其Enter方法使用您的团队、守门员、球员等都实现的另一个接口(它甚至可以是空的),那么它应该可以工作

public class FSM
{
    public /*some type*/ owner;         // PROBLEM 1
                                        // OWNER CAN BE TEAM, GOALKEEPEEPER
                                        // OR FIELD PLAYER
    public /*some type*/ globalState;
    public /*some type*/ currentState;
    public /*some type*/ previousState;
    public void Update()
    {
        if (globalState != null)
        {
            globalState.Execute(owner);  // PROBLEM 2
                                         // IF GLOBAL STATE'S TYPE
                                         // IS AN OBJECT, CANT CALL EXECUTE
                                         // OBJECTS TYPE WILL BE KNOWN ONLY
                                         // DURING RUNTIME
        }
     }
}

我应该改变整个设计吗?如果是,怎么做?看起来抽象类不需要是泛型的。您可以将抽象类设置为普通对象,并在每个对象中实现该抽象类。然后,您可以将状态类型属性添加到FSM类中。在进一步阅读之后,您实际上需要将State设置为一个普通接口,因为在该抽象类中没有基础工作。@CalebKeith如何用不同的参数覆盖虚拟方法?Enter(守门员gk)和Enter(团队)覆盖虚拟方法Enter(T项)来自国家级。你需要让你的球员、守门员、球队等等。。类也都有一个公共接口。您还可以将泛型对象作为参数,并在执行工作之前检查其类型。我的意思是,这很难给出一个准确的答案,因为我不完全了解你的代码。
public class FSM
{
    public /*some type*/ owner;         // PROBLEM 1
                                        // OWNER CAN BE TEAM, GOALKEEPEEPER
                                        // OR FIELD PLAYER
    public /*some type*/ globalState;
    public /*some type*/ currentState;
    public /*some type*/ previousState;
    public void Update()
    {
        if (globalState != null)
        {
            globalState.Execute(owner);  // PROBLEM 2
                                         // IF GLOBAL STATE'S TYPE
                                         // IS AN OBJECT, CANT CALL EXECUTE
                                         // OBJECTS TYPE WILL BE KNOWN ONLY
                                         // DURING RUNTIME
        }
     }
}
public interface IOwner {}

public interface IState
{
    void Enter(IOwner item);
}
public class ChaseState : IState
{
    public void Enter(IOwner pl)
    {
        // ...
        //...
    }
}
public class Player :IOwner { }
public class Something {
    IOwner owner = new Team();
    IState globalState = new ChaseState();
    IState currentState = new DefendState();

    public void Update()
    {
        if (globalState != null)
        {
            globalState.Enter(owner); 
        }
        else if (currentState != null)
        {
            currentState.Enter(owner);
        }
     }
}