Is it OK for an object to subscribe to its own events to change internal data?

Viewed 65

As the title says, is it reasonable for an object to subscribe to its own events?

public class Player
{
    private int team;

    public Action<int> TeamChanged { get; set; }

    public Player(int startingTeam)
    {
        team = startingTeam;

        TeamChanged += OnTeamChanged; // subscribe to my own event
    }

    private void OnTeamChanged(int newTeam)
    {
        team = newTeam;
    }
}

// later during the match:
public void ShuffleTeam()
{
    player.TeamChanged(GetRandomTeam());
}

It seems a lot more succinct than having an extra ChangeTeam() function, which invokes the event itself. But also feels wrong for some reason.

1 Answers

You seem to be understanding events upside down. And event is fired when something happens, you don't fire an event to make that something happen; you call a method.

In your case, when the Team property changes, you fire the event. You don't fire the event to make the team change. You need to change team? Implement a public method or property setter that does precisely that and let whoever wants to change teams, change.

Also, declare an event as an event, nos as a delegate. A correct way to approach your problem would be:

public class Player
{
    public event Action<int> TeamChanged;

    private int team;
    public int Team 
    {
        get { return team; }
        set 
        {
            if (value != team) {
                team = value;
                OnTeamChanged(team); } 
        } 
    }

    public Player(int startingTeam)
    {
        team = startingTeam; 
    }

    private void OnTeamChanged(int newTeam)
    {
        TeamChanged?.Invoke(team);
    }
}

And now any consumer who needs to act upon a player changing team would subscribe to the event.

You can also skip the whole OnTeamChanged business and raise the event directly in the property setter unless you are thinking in some inheritance model, in which case the method should be protected.

To make a long story short, subcribing to an own event makes no sense at all. Event driven design is useful precisely because you can't control or know when an event will fire; a user pressing a mouse button or closing an application. With an event declared in the class itself you always know when it will be raised, you've had to implement the call somewhere, subscribing to it is nonsensical.

Related