Interface for comparing two classes

Hi,
I’ve got an interface IState which is used by several concrete classes, StateStop, StateForward and StateTurn etc.

In my while-loop I’ve got an if-sentence to compare if the currentstate and the new state is different or not.

I’m doing;
if (currentState != newState)
//Do stuff

But the if always triggers, even if the newState is the same as the old one. Then I remember something about ICompare, IComparable, IEquality etc. Which is the one I should implement so that the if-sentence works?

You probably comparing two different instances of the same class.

Can you show how do you declare you currentState and newState variables?
Also please show where you change these variables.

This can be useful as well a StaMa framework discussed here:

https://www.ghielectronics.com/community/forum/topic?id=12642&page=1

The check is done on line 43 in this code:

https://github.com/Scalpel78/FolkraceUndertaker/blob/master/Undertaker/Undertaker/Car.cs

The line above calls AnalyzeSensors, and that returns a State object. This can for instance be a StateDriveForward, a StateTurn or a StateWaiting class.

If the new state is different than the previous one then I want to change into that new state.

One additional thing - the StateTurn class takes in a value to indicate how many degrees to turn the wheels. So the comparison must take this into consideration when comparing if the current StateTurn (with 30 degree turn) is different than the new StateTurn (with 45 degree turn).

you might want to use the Lock statement when updating/comparing the variables, to make sure only one instance has access to it at the time…

@ Scalpel78 - Yes the problem is that you are returning a new instance for a state each time the state transition happens.

You do need a method to compare instances or implement IComparable. Or you can override Equality operator. You might need a base common class from which all state classes will derive in addition or instead of the common interface.

There are some other problems. The state management you have implemented gives unnecessary work to the garbage collector and fragmenting the memory. If you state changes happen often this might affect performance significantly.

If you want to keep classes for your states I would create a pool of the states instances and will reuse them, something like this:


            IState[] states = { new StateTurn(),
                              new StateWaiting()
                          };

            IState turnState = states[0];
            (turnState as StateTurn).Angle = 45;

Jay Jay, where do you mean? Which variables?

Architech, I’ll look into overriding Equality operator.
What if I, for simplicity, just override ToString(), and just compare those?

@ Scalpel78 - You can, but it is not very effective and not much simpler than just comparing two objects. You can compare using a.GetType() == b.GetType(). That would be true if objects are of the same type. And if the type is StateTurn then you can compare angles. Wrap it into a function it would be less than 10 lines of code.

There’s a few things I’d reconsider in this code Scalpel.

First there’s nothing to be gained by representing different states with different classes, you can but it adds nothing helpful.

It may be better to define an enum - and list each of the states you want to represent as distinct enum members.

Then wherever you want to store a state value, just declare and use and instance of the enum.

For example we might have:

public enum State
{
Dormant, // i.e. parked, no key in ignition
Starting,
Parked,
Driving
}

and so on…

You can then have a member (field) in your ‘Car’ object of type ‘State’ - that field is then the state of the car.

It’s easy to compare enum and write code like this:

if (_currentState == State.Driving && desiredAction == Action.Start)
/// perhaps report an error…

You probably get the idea, basically your over-designing the way you represent state - unless there’s more to your work than I can see currently.

If you really must compare as you are, then because each state is a different class you can just compare their types:

if (state_a.GetType() == state_b.GetType()) // same…

or…

if (state_a is StateWaiting) // etc etc…

H