我试图进入C#泛型并创建了一个状态模式的状态机,现在我尝试重构.
我有一个状态,它引用了它正在处理的对象.
public abstract class AbstractState<T> where T : StatefulObject {
protected T statefulObject;
public AbstractState(T statefulObject) {
this.statefulObject = statefulObject;
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个有状态的对象,这应该引用它的当前状态.
public abstract class StatefulObject<T> : MonoBehaviour where T : AbstractState<StatefulObject<T>> {
public T state;
}
Run Code Online (Sandbox Code Playgroud)
但它不起作用("类型不能用作泛型类型或方法中的类型参数't').
我想要实现的是这样的:
public class Monster : StatefulObject<MonsterState> {
}
public abstract class MonsterState : AbstractState<Monster> {
}
Run Code Online (Sandbox Code Playgroud)
这可能吗?如果不是这样,还有另一个吗?谢谢.
您可以滥用接口和差异来实现这一点:
public interface IState<out TObject, in TState>
where TObject : IStatefulObject<TObject, TState>
where TState : IState<TObject, TState>
{
}
public interface IStatefulObject<in TObject, out TState>
where TObject : IStatefulObject<TObject, TState>
where TState : IState<TObject, TState>
{
}
public abstract class AbstractState<TObject> : IState<TObject, AbstractState<TObject>>
where TObject : IStatefulObject<TObject, AbstractState<TObject>>
{
protected TObject Object { get; private set; }
public AbstractState(TObject obj)
{
Object = obj;
}
}
public abstract class StatefulObject<TState> : IStatefulObject<StatefulObject<TState>, TState>
where TState : IState<StatefulObject<TState>, TState>
{
protected TState State { get; set; }
}
public class Monster : StatefulObject<MonsterState>
{
public Monster()
{
State = new IdleMonsterState(this);
}
}
public abstract class MonsterState : AbstractState<Monster>
{
protected MonsterState(Monster monster)
: base(monster)
{
}
}
public class IdleMonsterState : MonsterState
{
public IdleMonsterState(Monster monster)
: base(monster)
{
}
}
Run Code Online (Sandbox Code Playgroud)
这是否真的是一个好主意值得怀疑,这样的代码可能太混乱了。
您还可以采用更简单(但类型不太强)的方法:
public abstract class AbstractState
{
}
public abstract class StatefulObject
{
}
public abstract class AbstractState<TObject> : AbstractState
where TObject : StatefulObject
{
protected TObject Object { get; private set; }
public AbstractState(TObject obj)
{
Object = obj;
}
}
public abstract class StatefulObject<TState> : StatefulObject
where TState : AbstractState
{
protected TState State { get; set; }
}
public class Monster : StatefulObject<MonsterState>
{
}
public abstract class MonsterState : AbstractState<Monster>
{
protected MonsterState(Monster monster)
: base(monster)
{
}
}
Run Code Online (Sandbox Code Playgroud)
这并不能确保您无法分配,例如 aPlayerState到 a Monster,您应该在运行时检查。
| 归档时间: |
|
| 查看次数: |
482 次 |
| 最近记录: |