I have a StateMachine
class that needs to receive an initial State
value in the constructor so that the the crntState
and nextState
would not be null at construction.
public class StateMachine {
State crntState;
State nextState;
public StateMachine(State initialState) {
crntState = initialState;
nextState = crntState;
}
}
Problem is that I need to first create the value in the inheriting class's constructor before passing it to the base, since the IdleState
constructor requires a reference to MovementSM
class MovementSM : StateMachine {
Player player;
IdleState idleState;
MovingState movingState;
public MovementSM(Player player) : base(/*I want to pass idleState here*/) {
this.player = player;
idleState = new IdleState(this); //idleState can be declared only after the call to the base constructor
movingState = new MovingState(this);
}
}
I realize that I can initialize crntState
and nextState
in a seperate function and call it from MovementSM
's constructor, but then the compiler gives a warning that the non-nullable fields of crntState
and nextState
must contain non-null value when exiting the constructor.
I could make them nullable, but they don't have any logical reason to be nullable in the program.
I could also assign them dummy values in the constructor before assigning them actual values in the separate function, but that just defeats the whole purpose of making sure the fields are being assigned at construction, plus this idea includes a pointless step of assignment to crntState
and nextState
just to keep the compiler quite...
So with all that considered, what is the best way of addressing that problem?
EDIT:
Some people suggested that if I removed the need to pass this
to the state constructors, I could pass new IdleState()
to the base, and get it back to idleState
by doing idleState = crntState
. Beside thinking that passing this
is the correct solution in my case (explanation in the comments), I think passing the value first to the base could be really ugly.
For exmaple, I have this same problem with an Animation
instance that I wanted to pass from a class to it's base, and it looks like that:
walk = new Animation(new[]{
(new IntRect(16, 0, 16, 32), new Vector2i(0, 0), 0.2f),
(new IntRect(32, 0, 16, 32), new Vector2i(0, 0), 0.2f),
(new IntRect(16, 0, 16, 32), new Vector2i(0, 0), 0.2f),
(new IntRect( 0, 0, 16, 32), new Vector2i(0, 0), 0.2f),
});
Putting all that in a the base call just to later do walk = crntAnimation
is really ugly in my opinion.
Even more so, what if I wanted to generate that value using a for loop for example? Then passing it to base first would not only be ugly, but impossible.