Delegates

  • Thread starter Thread starter kode
  • Start date Start date
K

kode

im having problems trying to understand the delegates in
c#, does anybody know some link where i can find a good
and simple explanation?

thanks
 
there's also a pretty good chapter in Jesse Liberty's C#
book, which just happens to be available FREE ONLINE
http://www.oreilly.com/catalog/progcsharp3/chapter/ch12.pd
f

cheers!

btw his discussion of why events have the accessors they
do is dumb, but that's another story..

-----Original Message-----
kode,

Check out the section of the .NET framework documentation titled
"Delegates Tutorial", located at (watch for line wrap):

http://msdn.microsoft.com/library/default.asp? url=/library/en-us/csref/html/vcwlkdelegatestutorial.asp

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

im having problems trying to understand the delegates in
c#, does anybody know some link where i can find a good
and simple explanation?

thanks


.
 
would b hacker said:
btw his discussion of why events have the accessors they
do is dumb, but that's another story..

What's "dumb" about it? Makes perfect sense to me.
 
the problem with the event model is that it offers an add-
remove syntax which prevents retrieving any delegates
that have been assigned to the event. this means that
you can't retrieve event handlers in reflection, for
instance you can't copy event handlers from one object to
another.

according to liberty, this is to prevent objects with
access to the event (Main in liberty's example) from
impersonating the event (Main causing the printing of a
fictitious time on the console). this kind of issue is
silly, of coures main can do all kinds of wierd stuff if
it really wants, requiring that main not hijack events
should be a matter of style not language grammar.

btw does anybody know if there is a pre-c# history to the
event model that c# simply copied, or is the add/remove
event model novel with c#?
 
The concern is more about accidental problems as opposed to malicious
intent. If you could assign directly, you'd be able to write:

appDomain.DomainLoadEvent = new EventHandler(routine);

If somebody was already hooked up to the event, you would have just unhooked
them. Which would be bad.
--
Eric Gunnerson

Visit the C# product team at http://www.csharp.net
Eric's blog is at http://blogs.gotdotnet.com/ericgu/

This posting is provided "AS IS" with no warranties, and confers no rights.
 
wood bee hacker said:
the problem with the event model is that it offers an add-
remove syntax which prevents retrieving any delegates
that have been assigned to the event. this means that
you can't retrieve event handlers in reflection, for
instance you can't copy event handlers from one object to
another.

Which is good in many ways - if a class *wants* to expose which
handlers are being used, it can do so, but it doesn't *have* to.
according to liberty, this is to prevent objects with
access to the event (Main in liberty's example) from
impersonating the event (Main causing the printing of a
fictitious time on the console). this kind of issue is
silly, of coures main can do all kinds of wierd stuff if
it really wants, requiring that main not hijack events
should be a matter of style not language grammar.

No, because it helps to stop mistakes happening, just like strong
typing, access modifiers and the like. Would you suggest that
everything should be public as well? It's the same kind of argument.
btw does anybody know if there is a pre-c# history to the
event model that c# simply copied, or is the add/remove
event model novel with c#?

Don't know, to be honest.
 
news.microsoft.com said:
I can still app hijack with PostMessage and subclassing outside the runtime.

Sure. It's not absolutely preventing you from doing horrible thing -
but it's making life easier for those of us who don't *want* to do
nasty things, but would make mistakes if it were really easy to do
those things.
 
news.microsoft.com said:
Its something .NET should have addressed. An unsecure app message queue.

But that's completely unrelated to whether or not the idea of events is
good or not.
 
i agree, with caveat below, and you raise a very
reasonable concern-- but also one that i would address
very simply. seems to me that the correct way to enable
reflection would be to change the "add/remove" paradigm
to "add/remove/get". then for instance to do a copy you
would use get followed by a += loop. your accidental
problem below wouldnt happen because there is no "set".
you might not even call the new accessor "get" but rather
a cast of the event to a MulticastDelegate.

now the caveat: the current model actually DOES allow
you to write the accidental errant code exactly as you
just proposed-- provided 2 conditions are met. First,
your errant code must appear in the class which declares
the event rather than in a different class-- admittedly
not a common scenario since it is normally external
objects which register event handlers. Second, the event
must have been declared using the (more common) variable-
declarators form rather than the member-name (accessor)
form.

voila: i kid you not-- try it! if you write the
statement in one class you get a compiler error, in
another class you don't (even though the declaration is
marked "public"). if you declare the event using one
syntax you get a compiler error, using the alternate
syntax you don't. now i bet you didnt know that, and i
bet most programmers don't know that, so i submit that if
you dont agree with me that the event grammar is bogus,
you should at least agree that it is OBSCURE.

back to working with reality the way it is, do you happen
to know who actually designed this into the c# grammar?
are there any discussion threads or anybody who would
remember what they were actually thinking or where they
got their model or inspiration from? i am indeed
curious!!
 
wood bee hacker said:
i agree, with caveat below, and you raise a very
reasonable concern-- but also one that i would address
very simply. seems to me that the correct way to enable
reflection would be to change the "add/remove" paradigm
to "add/remove/get". then for instance to do a copy you
would use get followed by a += loop. your accidental
problem below wouldnt happen because there is no "set".
you might not even call the new accessor "get" but rather
a cast of the event to a MulticastDelegate.

If you want to provide that functionality, I don't believe there's
anything stopping you from doing so - you can write your own code to
store the event handlers, and then provide a way of accessing them.
now the caveat: the current model actually DOES allow
you to write the accidental errant code exactly as you
just proposed-- provided 2 conditions are met. First,
your errant code must appear in the class which declares
the event rather than in a different class-- admittedly
not a common scenario since it is normally external
objects which register event handlers. Second, the event
must have been declared using the (more common) variable-
declarators form rather than the member-name (accessor)
form.

voila: i kid you not-- try it!

No need to, I believe you.
if you write the
statement in one class you get a compiler error, in
another class you don't (even though the declaration is
marked "public").

And that's pretty reasonable, given the intention. I don't think it's
that odd to automatically give the class itself rather more control
over the event.
if you declare the event using one
syntax you get a compiler error, using the alternate
syntax you don't. now i bet you didnt know that, and i
bet most programmers don't know that, so i submit that if
you dont agree with me that the event grammar is bogus,
you should at least agree that it is OBSCURE.

It's obscure, but you won't run into it unless you're trying to do
something that very few people will want or need to do. I don't have
much of a problem with that. I also don't *think* it's guaranteed by
the C# spec - it's due to the way that the MS C# compiler *happens* to
pick the same variable name for the field as for the event (rather than
__eventName as the C# spec example suggests as a possibility). *That*
is a bit of a pity, I agree. (In that people may start relying on it
when they shouldn't.)
back to working with reality the way it is, do you happen
to know who actually designed this into the c# grammar?
are there any discussion threads or anybody who would
remember what they were actually thinking or where they
got their model or inspiration from? i am indeed
curious!!

I don't know of any discussions about it - but then I arrived fairly
late on the C# scene.
 
thanks jon, especially for the insight about fields v
events!

here's a simple thing i want to do, is there a simple or
standard way to do it? i want to VSDesigner a template
TreeView object and copy it at runtime to a new TreeView
() object. i can copy the properties no problem using
reflection, how do i copy the events?

known but tacky solutions are: manually += the events in
code rather than Designer (yuk), or wrap TreeView and
manually supply the functionality as you mention
previously (awkward, and breaks if TreeView changes).

thanks in advance!
 
wood bee hacker said:
thanks jon, especially for the insight about fields v
events!

here's a simple thing i want to do, is there a simple or
standard way to do it? i want to VSDesigner a template
TreeView object and copy it at runtime to a new TreeView
() object. i can copy the properties no problem using
reflection, how do i copy the events?

Well, I'd suggest using Clone, but that doesn't exist for TreeView. Of
course, you could derive from TreeView yourself, and call
Object.MemberwiseClone from there, but then I suspect your event
handlers would be really tied to each other.
known but tacky solutions are: manually += the events in
code rather than Designer (yuk), or wrap TreeView and
manually supply the functionality as you mention
previously (awkward, and breaks if TreeView changes).

I don't know of any other way, to be honest.
 
--
Eric Gunnerson

Visit the C# product team at http://www.csharp.net
Eric's blog is at http://blogs.gotdotnet.com/ericgu/

This posting is provided "AS IS" with no warranties, and confers no rights.
wood bee hacker said:
i agree, with caveat below, and you raise a very
reasonable concern-- but also one that i would address
very simply. seems to me that the correct way to enable
reflection would be to change the "add/remove" paradigm
to "add/remove/get". then for instance to do a copy you
would use get followed by a += loop. your accidental
problem below wouldnt happen because there is no "set".
you might not even call the new accessor "get" but rather
a cast of the event to a MulticastDelegate.

Can you explain the scenario where you need to do this?
now the caveat: the current model actually DOES allow
you to write the accidental errant code exactly as you
just proposed-- provided 2 conditions are met. First,
your errant code must appear in the class which declares
the event rather than in a different class-- admittedly
not a common scenario since it is normally external
objects which register event handlers. Second, the event
must have been declared using the (more common) variable-
declarators form rather than the member-name (accessor)
form.

A class that defines the event owns the underlying delegate, and can do
whatever it wants to it. It needs full access so that it can do things such
as calling GetInvocationList(). This is roughly analogous to properties, in
which the defining class has full control of the backing store.
voila: i kid you not-- try it! if you write the
statement in one class you get a compiler error, in
another class you don't (even though the declaration is
marked "public"). if you declare the event using one
syntax you get a compiler error, using the alternate
syntax you don't. now i bet you didnt know that, and i
bet most programmers don't know that, so i submit that if
you dont agree with me that the event grammar is bogus,
you should at least agree that it is OBSCURE.

If you use the advanced syntax - and it's pretty rare that you would *want*
to do so - you can cause the same problems if you write your code
incorrectly.
back to working with reality the way it is, do you happen
to know who actually designed this into the c# grammar?
are there any discussion threads or anybody who would
remember what they were actually thinking or where they
got their model or inspiration from? i am indeed
curious!!

The feature was designed by the C# language design team, and I was a member
at the time we did events.
 
Back
Top