Convert data type from inherited classes in C#
I am trying to understand inheritance for my unity project but seem to have found a limitation to my setup. I got my self confused whilst writing it as i am still learning to understand C# properly.
I have a set of classes that inherit, and they split based on two different behaviors that way i have the correct reference.
I then need to cast them so i can have access to a method in one of these classes. So my structure looks like this:
public class Behaviour : Position {
public Handler reference;
public Behaviour(int tx, int ty, Handler refer) : base (tx,ty){
reference = refer;
}
// overload
public Behaviour(int tx, int ty) : base (tx,ty){}
}
public class Behaviour2 : Position {
public SettingsHandler reference;
public Behaviour2(int tx, int ty, SettingsHandler refer) : base (tx,ty) {
reference = refer;
}
}
public class SettingsHandler : Handler {
public Settings level {get;set;}
}
public class Handler : MonoBehaviour{
virtual public void Enter(List<Node> n,Vector3 p){}
virtual public void Exit(List<Node> n, Node curNode){}
}
Now this was working fine until i had to access Handler.Enter or Handle.Exit. Then i got lost on how to set the type properly.
So I was doing something like this:
//need to set temp :
??? temp;
if(path[i] is Behaviour2){
temp = (Behaviour2)path[i];
} else {
temp = (Behaviour)path[i];
}
temp.reference.Enter();
What should temp type be set to here?
I am thinking i might have misunderstood inheritance as i seem to get type issues. Does C# have a solution for this - i can't be the only one who has got stuck. But my brain is getting confused trying to follow it all.
Your problem stems from the fact that the base classes are poorly designed in the first place, in the following ways:
The hierarchy makes no sense. A behaviour is not a special kind of position. Prefer composition to inheritance.
Fields should never be public. Use properties, not fields.
"is" checks are runtime type checks; don't do runtime type checks for polymorphic behaviour; use virtual methods.
Let's redesign your hierarchy.
abstract class MyBehaviour
{
public Position Position { get; private set; }
public Handler Handler { get; private set; }
protected MyBehaviour(int x, int y, Handler handler) {
this.Position = new Position(x, y);
this.Handler = handler;
}
}
class Behaviour1 : MyBehaviour {
/* Whatever */
}
class Behaviour2 : MyBehaviour {
/* Whatever */
}
All right, and now when we want to execute the handler...
MyBehaviour b = whatever;
b.Handler.Enter();
Done. No temporary variable needed. No runtime type check. No "if". The behaviour provides a service; you use the service. You should not have to ask the behaviour its type in order to use the service it provides; if you do, something is probably wrong at the design level.
In game engines, you simply take a "game object" and add behaviors.
It's that simple - end of story.
{In Unity "adding a behavior" is literally adding what they call a Component
class.}
You can't "derive" or "subclass" a game object - it's totally, completely, meaningless.
Unity is not a "programming language". Unity has no connection, at all, in any way, to "Object Oriented" - or anything else, at all, to do with programming. A game engine is not a programming language and has no connection to it.
To simply repeat: You can't "derive" or "subclass" a game object - that would be totally, completely, meaningless.
Say you have the following "behaviors" which you have written:
(You may have written them in c#, COBOL, machine code, whatever. That's totally irrelevant. They are behaviors .. Component
items in Unity.)
- can fly through air
- causes splash damage
- causes melting damage
- has glowing sphere around it
- has an icon attached
- explodes after ten seconds
- explodes on touching the ground
- has a whooshing sound
Say you have a game object "weapon".
To make a "grenade" you'd add these behaviors:
- can fly through air
- causes splash damage
- explodes on touching the ground
However, to make a "laser bomb", you'd instead add these behaviors:
- can fly through air
- explodes after ten seconds
- causes melting damage
- has glowing sphere around it
That's how game development works.
There is no connection, at all, to subclassing, etc.
In game engines, you simply take a "game object" and add behaviors.
In Unity "adding a behavior" is literally adding what they call a Component
class.