Help understanding delegates?

B

Brett

I'd like to better understand how the following code works. I've posted
questions below.

namespace Something.Something1
{
using System;

public delegate void Test1();
public delegate void Test2(ink k);

public class A
{
public static void Log1 (int l)
{
Console.WriteLine(":{0}",l);
}

public void Log2 (int l)
{
Console.WriteLine("#{0}",l);
}
}

public class Class1
{
public static void Main()
{
A a = new A();
Test2 t0 = new Test2(A.Log1); //use static method
Test2 t1 = new Test2(a.Log2); //use instance method

t0 += t1; t0(0);
t0 -= t1; t0(1);
}
}
}

This will print ":0 #0 :1". How does Log1 print 0 when no param is passed
to it and "l" is not initialized to 0?

What are the differences in the static and instance method calls via
delegates?

This line t0 -= t1; t0(1); removes those methods from the delegate
collection correct? How is the output affected if that line does not
exists?



Also, if I'm using the IE object and have three successive page loads, will
each of the following events respectively fire after each page load rather
than all three always firing after each page load? In other words, after
the first page load completes, onIEDocComplete1 fires. After the second
page load completes, onIEDocComplete2 fires. After the third page load
completes, onIEDocComplete3 fires.

IE_Inst.DocumentComplete += new
SHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(this.onIEDocComplete1);

IE_Inst.DocumentComplete += new
SHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(this.onIEDocComplete2);

IE_Inst.DocumentComplete += new
SHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(this.onIEDocComplete3);

Thanks,
Brett
 
M

Mattias Sjögren

How does Log1 print 0 when no param is passed
to it and "l" is not initialized to 0?

What do you mean no param is passed to it? You're passing 0 when
invoking the delegate so that's the value l will get.

What are the differences in the static and instance method calls via
delegates?

No differences apart from the ones seen in regular method calls.

This line t0 -= t1; t0(1); removes those methods from the delegate
collection correct?

It removes the t1 methods (Log2) from t0, but leaves Log1.

How is the output affected if that line does not exists?

Why don't you try it and see.



Mattias
 
B

Brett

Mattias Sjögren said:
What do you mean no param is passed to it? You're passing 0 when
invoking the delegate so that's the value l will get.

I mean to say t1 or Log2. Zero is not passed it yet it is displayed.

Any suggestions on the IE question?
 
M

Mattias Sjögren

How does Log1 print 0 when no param is passed
I mean to say t1 or Log2. Zero is not passed it yet it is displayed.

Log2 is called with the argument 0 when you invoke the t0 delegate
because Log2 is in t0's list of methods to call after you do t0 += t1.

Any suggestions on the IE question?

No they will all fire for every load event. If that's not what you
want, you'll have to remove the onIEDocComplete1 handler and add the
onIEDocComplete2 one when onIEDocComplete1 is called.



Mattias
 
B

Brett

Mattias Sjögren said:
Log2 is called with the argument 0 when you invoke the t0 delegate
because Log2 is in t0's list of methods to call after you do t0 += t1.



No they will all fire for every load event. If that's not what you
want, you'll have to remove the onIEDocComplete1 handler and add the
onIEDocComplete2 one when onIEDocComplete1 is called.

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?

Brett
 
B

Brett

Mattias Sjögren said:
Log2 is called with the argument 0 when you invoke the t0 delegate
because Log2 is in t0's list of methods to call after you do t0 += t1.



No they will all fire for every load event. If that's not what you
want, you'll have to remove the onIEDocComplete1 handler and add the
onIEDocComplete2 one when onIEDocComplete1 is called.



Mattias

How exactly do I remove the IE delegate?

I try:

IE_Inst.DocumentComplete -=
SHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(this.onIEDocComplete);

Compiler says:
Method 'appname.IE.onIEDocComplete(object, ref object)' referenced without
parentheses

So I try
IE_Inst.DocumentComplete -=
SHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(this.onIEDocComplete());

Compiler says:
No overload for method 'onIEDocComplete' takes '0' arguments

Brett
 
M

Mattias Sjögren

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.

How exactly do I remove the IE delegate?

I try:

IE_Inst.DocumentComplete -=
SHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(this.onIEDocComplete);

Compiler says:
Method 'appname.IE.onIEDocComplete(object, ref object)' referenced without
parentheses

Insert the new keyword before the event type.

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



Mattias
 
J

Jon Skeet [C# MVP]

Mattias Sjögren said:
Correct, except that I believe the order they are called in is
undefined and implementation dependent.

Nope - the order is guaranteed. Have a look at the docs for
Delegate.Combine for a few more details.
 
J

Jon Skeet [C# MVP]

Jon Skeet said:
Nope - the order is guaranteed. Have a look at the docs for
Delegate.Combine for a few more details.

Sorry, looking further, I can't see anything that absolutely guarantees
that when you call Invoke, the delegates are executed in the
appropriate order. However, things like the C# specification assume
that that's going to happen, and I think it's a pretty reasonable
assumption to make.
 
W

Willy Denoyette [MVP]

Brett said:
How exactly do I remove the IE delegate?

I try:

IE_Inst.DocumentComplete -=
SHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(this.onIEDocComplete);


You are missing the "new"

IE_Inst.DocumentComplete -= new ....

Not sure why you don't take some time to read the Events tutorial in MSDN's
"C# Programmers Reference"

Willy.
 
B

Brett

Jon Skeet said:
Sorry, looking further, I can't see anything that absolutely guarantees
that when you call Invoke, the delegates are executed in the
appropriate order. However, things like the C# specification assume
that that's going to happen, and I think it's a pretty reasonable
assumption to make.
I thought C# collections didn't have order?
 
B

Brett

-
Willy Denoyette said:
You are missing the "new"

IE_Inst.DocumentComplete -= new ....

Not sure why you don't take some time to read the Events tutorial in
MSDN's "C# Programmers Reference"

Willy.

Because it's not so clear how the particular thing with IE OnLoad is done.
You get much better feedback here anyway.

Brett
 
W

Willy Denoyette [MVP]

Brett said:
-


Because it's not so clear how the particular thing with IE OnLoad is done.
You get much better feedback here anyway.

Brett

If you did consult the documentation first, it wouldn't (maybe) be necessary
to ask questions like this one and you wouldn't ask about delegates while in
fact you were asking about Events.

Willy.
 
B

Brett

Willy Denoyette said:
If you did consult the documentation first, it wouldn't (maybe) be
necessary to ask questions like this one and you wouldn't ask about
delegates while in fact you were asking about Events.

Willy.

Delegates and events are related. It's not uncommon that asking about one
brings up a question on the other...if you are a beginner.

Brett
 
J

Jon Skeet [C# MVP]

Brett said:
I thought C# collections didn't have order?

That entirely depends on the collection - and delegates aren't
collections in the normal sense anyway.
 
B

Brett

"..delegates aren't collections in the normal sense anyway."

What do you mean by that?
 
J

Jon Skeet [C# MVP]

Brett said:
"..delegates aren't collections in the normal sense anyway."

What do you mean by that?

Well, they don't implement ICollection, to start with.
 
B

Brett

Jon Skeet said:
Well, they don't implement ICollection, to start with.

What are they missing out on by not implementing ICollection? 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.

Thanks,
Brett
 
B

Brett

Jon Skeet said:
Well, they don't implement ICollection, to start with.

What benefits are there to using ICollection in this case? Isn't this still
a collection either way?

Brett
 
J

Jon Skeet [C# MVP]

Brett said:
What benefits are there to using ICollection in this case? Isn't this still
a collection either way?

It's no a collection in any normal sense of being able to manipulate
it. Yes, there's an invocation list associated with the event, but you
can only add to it (at either end) or remove from it, both of which
create a new list rather than changing the existing one.

If you're going to use that broad a definition of "collection", how
could you possibly say that collections in C#/.NET are unordered? An
array would count as a collection, and that *certainly* isn't
unordered. *Some* collections (usually maps) are unordered, but lists
are generally ordered.
 

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