2

I observed several Assign() procedures and noticed that events are generally ignored during the assignment. For example, the TBitmap assignment method does not copy the OnChange event. I want to know

  1. If it's a commonly accepted way to not copy the events during the assignment, i.e. if all users rely on the fact that the events are never - and should never be - copied during an assignation?
  2. Why the events are (at least commonly) not copied during an assignation?
  3. Or perhaps I'm wrong, and the events may perfectly be copied, just depending of the circumstances?

Regards

6
  • 1
    It is up to the component author to make this decision. I would imagine that events are commonly not copied as part of Assign because they are seen to define behaviour rather than state, in a very loose way. I suppose the other motivation is that an event implicitly contains a reference to another object. Assign is expected to copy values rather than references. It would be very troubling if you wrote, A.Assign(B); B.Free, and left A with a bunch of stale references to event handlers implemented by B. Commented Mar 7, 2017 at 13:54
  • 1
    @DavidHeffernan Presumably the method references held in B's event handlers don't belong to it... that would rather defeat the purpose, no? Will these not generally be references to methods belonging to external objects which have configured B? Commented Mar 7, 2017 at 14:04
  • 2
    That would often be the case. Perhaps my code sample was too simplistic. But there's a very clear danger of stale references. Commented Mar 7, 2017 at 14:12
  • 1
    You can't assume that. Suppose "B" has an "OnChange" event. And suppose "B", as a default in its constructor, had assigned it to one of it's own methods. If the event was copied in "Assign", then after B.Free, "A" would have a stale reference. Commented Mar 7, 2017 at 14:23
  • 1
    Some of my own components I've written, I would hate for events to be carried over to another instance - but some other components I've written, this would be extremely handy. Not just components either, but TPersistents in general. Commented Mar 7, 2017 at 14:47

1 Answer 1

5

I'm not aware of a 'rule' that dictates this, but I think you are right and it almost never happens. It's up to the component's author though, because Assign is introduced in TPersistent, but doesn't do anything by itself until you actually implement an override. Actually it throws an exception (X cannot be assigned to Y) by default.

And that's the power of Assign too. The source you assign from doesn't even have to be the same type of component, because every assignment is a custom implementation. In your TBitmap example, you could assign it to a TPicture, and you might even assign other types of graphics to TBitmap which would let those graphics draw themselves on the bitmap's canvas.

In most, if not all, cases I've encountered, Assign is about that: an assignment and sometimes even conversion of data (of state, if you like) of one object into another.

Events are different. It's not up to an object to have an event handler and manage it. It's not that object's job to make the decision that its subscribers also want to subscribe to the other object. The value of/pointer to the event handler is not part of the (relevant) data of the object.

It just exposes the possibility for others to listen to things that have happened to it, and if those things want to listen to the other object too, they just have to assign an event handler to those objects as well.

So to me it makes perfect sense that events aren't copied, and I think I've never included events in the Assign implementations that I've written myself.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.