Is there a difference between using the following? I have seen instructors do both.
public event EventHandler OnSelectedUnitChange;
vs.
public event Action OnSelectedUnitChange;
Is there a difference between using the following? I have seen instructors do both.
public event EventHandler OnSelectedUnitChange;
vs.
public event Action OnSelectedUnitChange;
Mostly after watching this:
How To Build An Event System in Unity
So I’m mostly curious if it matters.
An Action is a simple predefined delegate with no parameters. Matching methods would be things like
void Handle_OnSelectedUnitChange()
{
//do something
}
The event is called like this:
if(OnSelectedUnitChange!=null)
{
OnSelectedUnitChange();
}
or the better syntax which I’ll use for the rest of this post:
OnSelectedUnitChange?.Invoke(); //Combines the if check with the call, and only invokes if there are subscribers.
An alternate form of this allows you to pass one or more parameters by declaring the types
public event Action<Unit> OnSelectedUnitChange;
This method will require a signature taking in a Unit as a parameter
void HandleSelectedUnitChange(Unit unit)
{
//Do something with the unit
}
This event would be raised like this:
OnSelectedUnitChange?.Invoke(selectedUnit);
EventHandlers work a bit differently. They will always have two parameters, even when there are no parameters to pass…
So as declared above, the method subscribing to the event would need the parameters
object sender, EventArgs eventArgs
so
void HandleSelectedUnitChange(object sender, EventArgs eventArgs)
{
//do something
}
and called with
HandleSelectedUnitChange?.Invoke(this, EventArgs.Empty);
Note that in all cases that an EventHandler is used without explicit parameters, you will always pass EventArgs.Empty. As such, they don’t appear any more useful than an Action.
The real power is EventHandlers is in passing parameters…
Like Actions, if you have one parameter to pass, you can use generics…
public event EventHandler<Unit> OnSelectedUnitChange;
which matches this signature:
void HandleSelectedUnitChange(object sender, Unit unit)
and is invoked with
OnSelectedUnitChange?.Invoke(this, selectedUnit);
Even this doesn’t leverage the full power of the EventHandler. If you want to pass a lot of parameters, you can create a child class of EventArgs…
public class SelectedUnitChangedArgs : EventArgs
{
public Unit oldSelectedUnit;
public Unit selectedUnit;
}
public event EventHandler<SelectedUnitChangedArgs> OnSelectedUnitChange;
Now the handler is:
void HandleSelectedUnitChange(object sender, SelectedUnitChangedArgs args)
{
DoSomethingWith(args.oldSelectedUnit);
DoSomethingElseWith(args.selectedUnit);
}
and invoked with
Unit oldSelectedUnit = selectedUnit;
selectedUnit = unitToSelect;
OnSelectedUnitChange?.Invoke(this, new SelectedUnitChangedArgs {oldSelectedUnit = oldSelectedUnit, selectedUnit = selectedUnit});
Oh wow. Thanks Brian!
This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.