Anonymous Delegates On Button Press

I just inherited an interesting piece of code.
My head screams that this should be replaced, but I wanted to get some community opinion.

Essentially it has a button that on click sends messages out to various game objects, which can be set in the inspector. It is certainly interesting, but makes me quiver.

private bool mPressed;

public event System.Action<ButtonGUIBehavior> OnButtonPress;

[System.Serializable]
public class TargetedMessage
{
    public string messageToSend;
    public GameObject gObject;
}

public void Start()
{
    foreach (TargetedMessage message in OnClickMessages)
    {
        OnButtonPress += (junk => message.gObject.SendMessage(message.messageToSend));
    }
}

if (OnButtonPress != null)
     OnButtonPress(this);

Again, my programmer senses are tingeling, and I am about a hop skip and jump away from switching it out, but I wanted to get a second(or third) opinion on this. I did some light research and there were no red lights, at least not on the surface.

Thoughts? (articles also appreciated)

Thank you for your time.

Ugh - I think your senses are working ok.

Obviously events and delegates work fine and can be used well - but anonymous delegates can be a total disaster. When the thing that has OnButtonPress is alive it will hold in memory everything that has ever gone through that loop due to the closure formed over message.

Now it might be ok in this instance - about the only time it is OK is when you want everything to live for the duration of the object which may be the case here as it is configured in Start. The big problem of anonymous delegates is you can never remove them so they hold their closures open while the object with the event is reachable. It’s a huge source of memory leaks.

My view is to rarely form an anonymous delegate as an event handler like this and if I do then document and comment it explaining why it isn’t screwing everything up (which means if it actually is then at least someone can see why I thought it would work).

So: message will be held alive until this object goes out of scope and the code will throw errors if message.gObject is destroyed at any time before this item is destroyed.