Tom Benny
Tom Benny

Reputation: 73

What is the right way of implementation c# event

I'm stuck with event implementation in C# code. I have class Characters, which contains Name, HP, DMG and DEF. Then I have few random enemies and one hero based on Characters class.

Next I have method, what is picking random attacker and random defender. That means - I have Hero, Dragon, and Wolf. The method will pick random character, let's say the Hero and mark him as "defender". Then it will randomly pick between Dragon and Wolf and mark it as "attacker". And I want to create an event which will be triggered inside this method and it will show which characters are against. I.e. "Hero has chosen the Dragon as his opponent".

I've tried it like

public delegate void ChooseOpponentEventHandler(object source, EventArgs args);
public event ChooseOpponentEventHanlder ChooseEvent;

//Method for choosing random enemy
abstract public bool ChooseAttacker(string Attacker, string Defender);
virtual public bool ChooseOpponent(string Attacker, string Defender, int OppNum, int AttNum)
{
   if(ChooseAttacker(Attacker, Defender) == true && AttNum != OppNum 
   {
      return true;
   }
else return false;
}

protected virtual void OnChooseOpponent()
{
   if (ChooseEvent != null)
   ChooseEvent(this, Event.Args.Empty);
}

I have no idea how to put the method OnChooseOpponent() inside the ChooseOpponent() method and also how to make the Method say

Console.WriteLine(Attacker.Name + "has chosen" + Defender.Name + " as his opponent") 

or something like that, because the Method OnChooseOpponent doesn't know, who Attacker or Defender is.

Upvotes: 0

Views: 96

Answers (1)

Sotiris Panopoulos
Sotiris Panopoulos

Reputation: 1613

I can already see some compilation errors in your code.

First of all, it's EventArgs, not Event.Args. Then, the Attacker and the Defender are strings. They do not contain a .Name property or field.

As to how to handle your events, you want to notify other classes when the ChooseOpponent is executed, right? What you should do is simply call OnChooseOpoonent(); inside ChooseOpponent.

In order for another class to get notified, they should have an instance of this class, let's say it's named otherClass. What you need to do is:

otherClass.ChooseEvent += EventChosen;

void EventChosen(object sender, EventArgs e)
{
    Console.WriteLine("The event was chosen.");
}

Now, if you want to also pass some additional data with your event, you have to create a separate class that will be transfered along with your event:

public class ChooseEventArgs : EventArgs
{
   public string Attacker {get; set;}
   public string Defender {get; set;}
}

When you fire the event, it should be:

protected virtual void OnChooseOpponent(string attacker, string defender) 
{
    if (ChooseEvent != null)
    ChooseEvent(this, new ChooseEventArgs{Attacker = attacker, Defender = defender});
}

EDIT: as Gserg suggested, the proper way to fire (invoke) an event is with this piece of code instead:

protected virtual void OnChooseOpponent(string attacker, string defender) 
{
    ChooseEvent?.Invoke(this, new ChooseEventArgs{Attacker = attacker, Defender = defender});
}

And in your other class, you can change the signature of the method that will handle the event, like so:

void EventChosen(object sender, ChooseEventArgs e)
{
    Console.WriteLine(e.Attacker + " has chosen " + e.Defender + " as his opponent");
}

I hope that makes sense. To clear things up, you can read this documentation which might explain the concept better than I can.

Upvotes: 1

Related Questions