C# generics, cross referencing classes for state pattern -
i trying c# generics , have created state machine state pattern , try refactor.
i have state, has reference object it's working on.
public abstract class abstractstate<t> t : statefulobject { protected t statefulobject; public abstractstate(t statefulobject) { this.statefulobject = statefulobject; } }
and have object has states, should have reference current state.
public abstract class statefulobject<t> : monobehaviour t : abstractstate<statefulobject<t>> { public t state; }
but not work ("the type cannot used type parameter 't' in generic type or method").
what want achieve :
public class monster : statefulobject<monsterstate> { } public abstract class monsterstate : abstractstate<monster> { }
is possible? if it's not way, there another? thx.
you can abuse interfaces , variance achieve that:
public interface istate<out tobject, in tstate> tobject : istatefulobject<tobject, tstate> tstate : istate<tobject, tstate> { } public interface istatefulobject<in tobject, out tstate> tobject : istatefulobject<tobject, tstate> tstate : istate<tobject, tstate> { } public abstract class abstractstate<tobject> : istate<tobject, abstractstate<tobject>> 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> 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) { } }
whether it's idea dubious, such code may confusing.
you go simpler (but less strongly-typed) approach:
public abstract class abstractstate { } public abstract class statefulobject { } public abstract class abstractstate<tobject> : abstractstate tobject : statefulobject { protected tobject object { get; private set; } public abstractstate(tobject obj) { object = obj; } } public abstract class statefulobject<tstate> : statefulobject tstate : abstractstate { protected tstate state { get; set; } } public class monster : statefulobject<monsterstate> { } public abstract class monsterstate : abstractstate<monster> { protected monsterstate(monster monster) : base(monster) { } }
this won't ensure won't able assign, playerstate
monster
, should check @ runtime.
Comments
Post a Comment