Help understanding delegates?

J

Jon Skeet [C# MVP]

Brett said:
What are they missing out on by not implementing ICollection?

Well, there's nothing collection-like about the delegates themselves
unless you call GetInvocationList or Combine... To reverse the
question, in what way *are* delegates naturally collections?
Certain
features of the ICollection interface? How is that a big disadvantage? I'm
asking because I still get away with using a collection in this case and
don't notice any disadvantages.

What do you mean by "get away with using a collection"?
 
B

Brett

Jon Skeet said:
Well, there's nothing collection-like about the delegates themselves
unless you call GetInvocationList or Combine... To reverse the
question, in what way *are* delegates naturally collections?


What do you mean by "get away with using a collection"?

Perhaps it isn't a collection but just a list, as you have mentioned.
Probably just do a GetType() to determine it.

Brett
 
J

Jon Skeet [C# MVP]

Brett said:
Perhaps it isn't a collection but just a list, as you have mentioned.

The delegate itself isn't a list - it encapsulates a list of
invocations, but it isn't a list in itself.

When you say that you "still get away with using a collection in this
case" what exactly do you mean?
Probably just do a GetType() to determine it.

I don't see how that would help. Could you give an example of what you
mean?
 
B

Brett

Jon Skeet said:
The delegate itself isn't a list - it encapsulates a list of
invocations, but it isn't a list in itself.

When you say that you "still get away with using a collection in this
case" what exactly do you mean?


I don't see how that would help. Could you give an example of what you
mean?

I don't have an example. Was just trying to get a solid definition of what
this structure is that holds a list of events. First it was something that
behaved like a collection, then it was a list. Then not a list but
something encapsulating a list. One of us is very confused but I'm backing
off now. ; )

Thanks,
Brett
 
J

Jon Skeet [C# MVP]

Brett said:
I don't have an example. Was just trying to get a solid definition of what
this structure is that holds a list of events. First it was something that
behaved like a collection, then it was a list. Then not a list but
something encapsulating a list. One of us is very confused but I'm backing
off now. ; )

Basically, it contains a list. It's immutable, so you can't change the
list itself, only create a new delegate with a different list
containing the first list. You can't use it as a general purpose
collection, as it can only hold delegates.

The things you've said that confuse me most are:

1) That collections in C# aren't ordered
2) That you've used delegates as collections with no trouble
 
B

Brett

Jon Skeet said:
Basically, it contains a list. It's immutable, so you can't change the
list itself, only create a new delegate with a different list
containing the first list. You can't use it as a general purpose
collection, as it can only hold delegates.

The things you've said that confuse me most are:

1) That collections in C# aren't ordered
My fault.
2) That you've used delegates as collections with no trouble
I thought they were collections. I've read they were in some of the online
examples I've seen. That's how they are described. That's not a global
description of course. Perhaps this exchange with Mattias further up in
the thread did me in. You see it hits both of your questions.
[>So is a delegate basically a collection of method pointers that when
called,
executes all methods in the collection in the order they were added to the
collection?

Correct, except that I believe the order they are called in is
undefined and implementation dependent.]
 
S

Steve Walker

Brett <[email protected]> said:
I thought they were collections. I've read they were in some of the online
examples I've seen. That's how they are described. That's not a global
description of course.

I think this is just a case of terminology. It's quite common to use
"collection" to describe any container which can manage a number of
contained objects. I think Jon is using it in a stricter .NET specific
sense to mean "implements ICollection". I've got lots of classes
implementing IEnumerable which I would casually describe as
"collections", but by Jon's definition, they aren't.
 
B

Brett

Jon Skeet said:
Basically, it contains a list. It's immutable, so you can't change the
list itself, only create a new delegate with a different list
containing the first list. You can't use it as a general purpose
collection, as it can only hold delegates.

The things you've said that confuse me most are:

1) That collections in C# aren't ordered
2) That you've used delegates as collections with no trouble

While we're on the subject,. how can I removed all events I've delegated?
For example:

IE_Inst.DocumentComplete -= new
SHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(this.onIEDocCompleteGetMessages);

and at some later point clear out
IE_Inst.DocumentComplete

so that no event fires based on the page load complete.

Thanks,
Brett
 
J

Jon Skeet [C# MVP]

Brett said:
While we're on the subject,. how can I removed all events I've delegated?
For example:

IE_Inst.DocumentComplete -= new
SHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(this.onIEDocCompleteGetMessages);

and at some later point clear out
IE_Inst.DocumentComplete

so that no event fires based on the page load complete.

You can only remove specific handlers - so if you know what you've
added, you can remove them again - but you can't just clear out
everything.
 
M

mdb

Jon Skeet said:
You can only remove specific handlers - so if you know what you've
added, you can remove them again - but you can't just clear out
everything.

I think you would be able to iterate through the list of delegates (with
GetInvocationList) and remove each one. You probably can even tell whether
its something you've added (versus other classes) with the .Target and/or
..Method properties. Whether you can distinguish between two objects of the
same class with different events might be a bit more difficult, though.

-mdb
 
J

Jon Skeet [C# MVP]

mdb said:
I think you would be able to iterate through the list of delegates (with
GetInvocationList) and remove each one. You probably can even tell whether
its something you've added (versus other classes) with the .Target and/or
.Method properties. Whether you can distinguish between two objects of the
same class with different events might be a bit more difficult, though.

You can do that if you have access to the delegate - but if you only
have access to the *event*, you can't get the invocation list, only add
to it and remove from it.
 
B

Brett

Jon Skeet said:
You can do that if you have access to the delegate - but if you only
have access to the *event*, you can't get the invocation list, only add
to it and remove from it.

Using the example in my initial post, say I add two events to the deletgate
t0. Can I use a foreach loop to get at items stored in the t0 delegate
type?

Now, it isn't necessary that I implement IEnurmerable to use a for each
loop? I ask that question because every time I have used a for each loop, I
haven't implemented IEnumerable. However, from the docs:
[IEnumerable must be implemented to support the ForEach semantics of
Microsoft Visual Basic. COM classes that allow enumerators also implement
this interface.]

If the above is true, then t0 is a collection because IEnumerable is in the
System.Collections namespace.

Brett
 
S

Sean Hederman

Brett said:
Using the example in my initial post, say I add two events to the
deletgate t0. Can I use a foreach loop to get at items stored in the t0
delegate type?

IF you have access to the delegate object itself you can foreach through
Delegate.GetInvocationList which is an array. Arrays implement IList which
inherits from IEnumerable via ICollection.
Now, it isn't necessary that I implement IEnurmerable to use a for each
loop? I ask that question because every time I have used a for each loop,
I haven't implemented IEnumerable. However, from the docs:
[IEnumerable must be implemented to support the ForEach semantics of
Microsoft Visual Basic. COM classes that allow enumerators also implement
this interface.]

The object you are enumerating on must implement IEnumerable (the one in the
"in" part of your foreach).
If the above is true, then t0 is a collection because IEnumerable is in
the System.Collections namespace.

Sorry, wrong. DictionaryEntry, Comparer, and IHashCodeProvider are all in
the System.Collections namespace and are not collections. Being in the
namespace does not imply that they ARE collections, merely that they are
related to collections in some way. You're confusing location with identity.
Just to reinforce my point, t0.GetInvocationList returns an array which IS a
collection (since it implements ICollection), but Array resides in the
System namespace.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top