Delegate

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Tony Johansson

    Delegate

    Hello!!

    Below is a program copied from a book.
    The program is easy but there is one thing about the program that I would
    like to have some more info about.

    Assume that you have for example 10 cars in the array gameCars.
    Assume also that you want to subscribe to an event for some cars located in
    the array gameCars.

    Now to my question. There are two metods called Subscribe and Unsubscribe.
    When you subscript to an event for one or more cars located in the array
    gameCars how does the program know which cars
    you subscribe to because you don't include any this or will this object this
    be passed invisible to us. or is it in another way.
    The publisher is class GameController and subscriber is class Car.
    Just below is the method Subscribe which is the key to my question. Here you
    just add another instance of the event object MoveRequest and pass the
    eventhandler which should take care of the event when fired from the
    publisher GameController
    public void (GameController controller)
    {
    controller.OnMo veRequest += new MoveRequest(Mov eRequestHandler );
    }


    //Begin is the complete Program
    //*************** ********
    using System;
    enum MoveRequestType { FastForward, SlowForward, Reverse };

    class MoveRequestEven tArgs : EventArgs
    {
    private MoveRequestType request;

    public MoveRequestEven tArgs(MoveReque stType initRequest) : base()
    {
    request = initRequest;
    }

    public MoveRequestType Request
    {
    get
    {
    return request;
    }
    }
    }

    public delegate void MoveRequest(obj ect sender, MoveRequestEven tArgs e);

    class GameController
    {
    public event MoveRequest OnMoveRequest;
    Car[] gameCars = new Car[10];
    string carName;
    int speedParam = 0;
    int carCounter = 0;
    int carNumber = 0;

    public void Run()
    {
    string answer;
    Console.WriteLi ne("Please select from the following menu: ");
    Console.WriteLi ne("A)dd cal");
    Console.WriteLi ne("C)ar. Subscribe to events");
    Console.WriteLi ne("U)nsubscrib e from events");
    Console.WriteLi ne("L)ist cars in current game");
    Console.WriteLi ne("F)ast forward");
    Console.WriteLi ne("S)low forward");
    Console.WriteLi ne("R)everse") ;
    Console.WriteLi ne("T)erminate" );

    do
    {
    Console.WriteLi ne("Select new option:");
    answer = Console.ReadLin e().ToUpper();

    switch (answer)
    {
    case "A" :
    Console.WriteLi ne("Enter name of the new car: ");
    carName = Console.ReadLin e();
    Console.Write(" Enter car speed parameter of the new
    car: ");
    speedParam = Convert.ToInt32 (Console.ReadLi ne());
    gameCars[carCounter] = new Car(speedParam, carName);
    carCounter++;
    break;

    case "C":
    Console.WriteLi ne("Enter array index of car you want to
    subscribe to events: ");
    carNumber = Convert.ToInt32 (Console.ReadLi ne());
    gameCars[carNumber].Subscribe(this );
    break;

    case "U":
    Console.Write(" Enter array index of car you want to
    unscribe from event: ");
    carNumber = Convert.ToInt32 (Console.ReadLi ne());
    gameCars[carNumber].Unsubscribe(th is);
    break;

    case "L":
    for (int i= 0; i<carCounter; i++)
    Console.WriteLi ne(gameCars[i]);
    break;

    case "F":
    if (OnMoveRequest != null)
    OnMoveRequest(t his, new
    MoveRequestEven tArgs(MoveReque stType.FastForw ard));
    break;

    case "S":
    if (OnMoveRequest != null)
    OnMoveRequest(t his, new
    MoveRequestEven tArgs(MoveReque stType.SlowForw ard));
    break;

    case "R":
    if (OnMoveRequest != null)
    OnMoveRequest(t his, new
    MoveRequestEven tArgs(MoveReque stType.Reverse) );
    break;

    case "T":
    break;
    default:
    Console.WriteLi ne("Invalid choice. please try again");
    break;
    }
    }while(answer != "T");
    }
    }

    class Car
    {
    private int distance;
    private int speedParam;
    private string name;

    public Car(int initSpeedParam, string initName)
    {
    speedParam = initSpeedParam;
    distance = 0;
    name = initName;
    }

    public void Subscribe(GameC ontroller controller)
    {
    controller.OnMo veRequest += new MoveRequest(Mov eRequestHandler );
    }

    public void Unsubscribe(Gam eController controller)
    {
    controller.OnMo veRequest -= new MoveRequest(Mov eRequestHandler );
    }

    public void MoveRequestHand ler(object sender, MoveRequestEven tArgs e)
    {
    switch (e.Request)
    {
    case MoveRequestType .SlowForward:
    distance += speedParam;
    Console.WriteLi ne("Car name: " + name + "Moving slowly.
    Distance: " + distance);
    break;
    case MoveRequestType .FastForward:
    distance += speedParam * 2;
    Console.WriteLi ne("Car name: " + name + "Moving fast.
    Distance: " + distance);
    break;
    case MoveRequestType .Reverse:
    distance -= 5;
    Console.WriteLi ne("Car name: " + name + "Reversing Distance:
    " + distance);
    break;
    }
    }

    public override string ToString()
    {
    return name;
    }
    }

    class Tester
    {
    public static void Main()
    {
    GameController controller = new GameController( );
    controller.Run( );
    }
    }

    //Tony



  • Jon Skeet [C# MVP]

    #2
    Re: Delegate

    Tony Johansson <johansson.ande rsson@telia.com wrote:
    Below is a program copied from a book.
    The program is easy but there is one thing about the program that I would
    like to have some more info about.
    >
    Assume that you have for example 10 cars in the array gameCars.
    Assume also that you want to subscribe to an event for some cars located in
    the array gameCars.
    >
    Now to my question. There are two metods called Subscribe and Unsubscribe.
    When you subscript to an event for one or more cars located in the array
    gameCars how does the program know which cars
    you subscribe to because you don't include any this or will this object this
    be passed invisible to us. or is it in another way.
    The GameController doesn't really know what is subscribing to it - it
    just gets a delegate instance to effectively add to the list of
    delegate instances to call at the appropriate time. However, the
    delegate instances in question all use MoveRequestHand ler as the
    action. That's an instance method, so when you subscribe to an event
    using it there's an object associated with the delegate as well (the
    *target* of the delegate). It's implicitly "this" - the code:

    controller.OnMo veRequest += new MoveRequest(Mov eRequestHandler );

    is equivalent to:

    controller.OnMo veRequest += new MoveRequest(thi s.MoveRequestHa ndler);

    You could subscribe using a *different* car as the target of the
    delegate:

    controller.OnMo veRequest += new MoveRequest(oth er.MoveRequestH andler);

    If this isn't clear, try reading:

    Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

    and


    --
    Jon Skeet - <skeet@pobox.co m>
    http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
    World class .NET training in the UK: http://iterativetraining.co.uk

    Comment

    • Marc Gravell

      #3
      Re: Delegate

      The "this" is implicit, since Subscribe, Unsubscribe and
      MoveRequestHand ler are all instance methods. Hence, this is equivalent
      to the following ["this" added]. Each delegate knows about the
      specific instance *and* the method involved in the delegate's
      construction. Obviously things are slightly different if one-or-more
      of the methods is static.

      Does that answer the question?

      Marc

      public void Subscribe(GameC ontroller controller)
      {
      controller.OnMo veRequest += new
      MoveRequest(thi s.MoveRequestHa ndler);
      }


      public void Unsubscribe(Gam eController controller)
      {
      controller.OnMo veRequest -= new
      MoveRequest(thi s.MoveRequestHa ndler);
      }


      Comment

      Working...