Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
734 views
in Technique[技术] by (71.8m points)

inheritance - 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...