469,310 Members | 2,427 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,310 developers. It's quick & easy.

Delegates are useful, and here is why (sample program)

They usually don't teach you in most textbooks I've seen that
delegates can be used to call class methods from classes that are
'unaware' of the delegate, so long as the class has the same signature
for the method (i.e., as below, int Square (int)).

Here is an example to show that feature. Note class "UnAwareClass"
has its methods Square and Cuber called by a class DelegateClass.
This is because these methods in UnAwareClass have the same signature
and so they can be called by DelegateClass, without the keyword
'delegate' ever appearing in UnAwareClass.

Note the keyword 'static' has to be used as below, even though
UnAwareClass itself is not static, though there is a way to use
delegates with non-static functions (however I don't see the need to
do so).

Pretty cool if you ask me--like a functor in C++.

RL

//Delegate model showing how another class (“UnAwareClass”) does not
even have to be aware of the delegate and still be called and
employed.
///

///////
// OUTPUT (takes the square of a number, here 11, and the cube, to
give 121 and 1331)

...now for external use of delegates from two classes...
Square 11 is: 121
!Cube 11 is: 1331
Press any key to continue . . .
///////

using System;
using System.Collections.Generic;
using System.Text;

namespace EventDelegates
{
class Program
{
static void Main(string[] args)
{

UnAwareClass myUnAwareClass = new UnAwareClass();

// now to access delegate from another class

Console.WriteLine("...now for external use of delegates from two
classes...");

DelegateClass.PublicHigherPower2 sQr = new
DelegateClass.PublicHigherPower2(UnAwareClass.Squa re); //!!! Note: how
called: UnAwareClass.Square

DelegateClass myDelegateClass = new DelegateClass(); //
apparently no ill effects if follows rather than preceeds previous
line

int ji2 = myDelegateClass.DoOp(sQr, 11);

Console.WriteLine("Square 11 is: {0}", ji2);

DelegateClass.PublicHigherPower2 Cub2 = new
DelegateClass.PublicHigherPower2(UnAwareClass.Cube r);

//!!! note: how called: UnAwareClass.Cuber

ji2 = myDelegateClass.DoOp(Cub2, 11);

Console.WriteLine(" !Cube 11 is: {0}", ji2);

// !!!Note significance: 'delegate' keyword NEVER APPEARS in class
UnAwareClass (!)

}
}
}
////////////
using System;
using System.Collections.Generic;
using System.Text;

namespace EventDelegates
{
class UnAwareClass
{

//!! in this version, 'delegate' keyword does not appear in
this class (UnAwareClass) but only DelegateClass class

int[] values;
int i;
public UnAwareClass()
{
values = new int[] { 1, 2, 3 }; //not used
i = 22333; //not used
}
public static int Square(int x)
{
return x * x;
}
public static int Cuber(int y)
{
return y * y * y;
}
}

class DelegateClass
{
public delegate int PublicHigherPower2(int x); //delegate to
be used externally (keyword delegate must of course be declared here)

int j;
public DelegateClass()
{
j = 0;
}

public int DoOp(PublicHigherPower2 ar, int x) //note format
{
return ar(x);
}
}

}
Jul 13 '08
69 5150
forgive me if i sound like a voyeur here :), but i really enjoyed reading
this thread, and got many useful pointers for further study from it.

i found myself feeding the stray thought (they're often yowling in the back
alleys of my mind, those strays) that there might be a place for a neologism
:

algorighteousness

which would describe : "a state of inner conviction that a certain technical
strategem embodies a profound truth equal in importance to life itself with
an inherent tendency for the level of conviction to become more intense as
said strategem is debated."

the stray thought that made me think of this thread as the libretto of an
opera : i didn't feed.

regards, Bill
Jul 21 '08 #51
On Jul 21, 11:58*am, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
On Mon, 21 Jul 2008 07:47:00 -0700, Author <gnewsgr...@gmail.comwrote:
I have been closely following this thread these days. *Is it the case
that at the end of the day, delegate is only useful in event handling?

No. *I agree that a _multicast_ delegate is most commonly useful for event *
handling. *But delegates in general are useful in a much broader variety *
of scenarios. *Any time that you have code that wants to be able to *
execute some arbitrary code without knowing what that code is at compile *
time, a delegate is useful.

A couple of obvious examples include threaded invocations of code (see *
ThreadStart) and collection processing (for example, predicates used for *
searching, removing, or otherwise processing a collection).
Thank you.

I struggle to understand "code that wants to be able to execute some
arbitrary code without knowing what that code is at compile time".

Marc also says in the 2nd post of this thread that "Delegates become
useful when the code that invokes them cannot possibly know about the
actual methods (such as List<T>.Find)", which, too, I struggle to
understand.

I think the frustration comes from not understanding

what are the stuffs which the invoking method knows vs. what are the
stuffs which the invoking method does not know.

So, for example, in the following code,

Button b = new Button();
b.Text = "Click me";
b.Click += new System.EventHandler(b_Click);

we dynamically create a button control, and delegate its Click event
handler to b_Click method through newing System.EventHandler. Does
this mean that

1. we want the Click event of the button to be handled,
2. we don't know how it is gonna be handled,
3. if we know how the Click event should / will be handled, then we
simply code the logic at where "new System.EventHandler(b_Click)" is,
maybe through an anonymous method

?

Not sure if I am close.
Jul 21 '08 #52
On Mon, 21 Jul 2008 10:03:36 -0700, Author <gn********@gmail.comwrote:
[...]
I think the frustration comes from not understanding
what are the stuffs which the invoking method knows vs. what are the
stuffs which the invoking method does not know.
I feel your pain. To some extent, it's a matter of experience. You don't
say how much programming experience you have, but in the simplest systems,
this just doesn't come up at all. But in more real-world situations, and
especially in object-oriented programming, you start seeing code that
depends on some implementation detail being done at some later time and/or
by someone else.

Virtual functions are an example of this, as are interfaces and abstract
classes (two closely related concepts, which to some extent rely on the
concept of virtual functions). Function pointers are yet another, and
delegates are the C# form of function pointers. These all allow someone
to write some code A that calls an implementation B that is, at the time
that the code A is being written, does not exist or is otherwise unknown..

Until you've seen some actual examples (MSDN has a number of them, which
you should be able to find by searching on terms and examples used in this
thread), it can indeed be hard to really comprehend the use. Once you've
seen the examples and especially once you've been able to use the
techniques yourself, they start to make more sense.
So, for example, in the following code,

Button b = new Button();
b.Text = "Click me";
b.Click += new System.EventHandler(b_Click);

we dynamically create a button control, and delegate its Click event
handler to b_Click method through newing System.EventHandler. Does
this mean that

1. we want the Click event of the button to be handled,
Yes.
2. we don't know how it is gonna be handled,
yes.
3. if we know how the Click event should / will be handled, then we
simply code the logic at where "new System.EventHandler(b_Click)" is,
maybe through an anonymous method
No. That is, yes...you could write an anonymous method. But at the point
you suggest, you would still be taking advantage of the polymorphic
behavior of the delegate.

The _interesting_ part in the example you provided is the Click event
itself, not the delegate used to subscribe to the event. That is,
consider where that event exists. It's part of the Button class. Now,
who wrote the Button class? Was it you? No. It was Microsoft.

When Microsoft wrote the Button class, did they know you were going to
write a method named "b_Click" that would handle the Click event? No,
they didn't. But because of the idea of an event and a delegate that can
be subscribed to the event, they've provided a mechanism by which their
own code, written long before you came along, can call your code without
knowing anything specific about it at the time they wrote their code.

They define the signature of the method, and leave the rest up to you. As
long as you comply with the defined signature, you can have whatever code
you want execute when the Click event is raised, and it just works.

Even though Microsoft didn't talk to you before they implemented and
delivered the Button class to the world. :)

Pete
Jul 21 '08 #53
On Jul 21, 12:26*pm, "Jon Skeet [C# MVP]" <sk...@pobox.comwrote:
On Jul 21, 3:47 pm, Author <gnewsgr...@gmail.comwrote:
I have been closely following this thread these days. *Is it the case
that at the end of the day, delegate is only useful in event handling?

No, not at all. Delegates have become more useful over the course of
the evolution of the .NET framework, and they're a core part of LINQ.
I experimented with multicast delegate with the following code, but
got an exception which says: *Attempted to read or write protected
memory. This is often an indication that other memory is corrupt.
The code itself seems to be OK. What does this exception really
mean?

Something is very wrong on your machine. It could be the .NET
installation, some bad memory, or something else. The code's fine
though.
BTW, I don't understand how useful multicast delegate can be. *It
seems to me that its only purpose is to "simplify" calling multiple
methods with one call. *But all methods have to have the same
signature and all of them have to be registered with the given
multicast delegate. *Plus, how often does it happen that multiple
methods have the same signature, return void, and need to be called
one after another?

It's very useful for events, to start with. Why should you be limited
to having *one* way of responding to a click, for instance? Multicast
delegates allow for composition of event handlers very neatly.

I've also used them in "Push LNQ" for situations where I've wanted to
compute multiple aggregates from a single input source. I agree that
the uses are relatively limited, but it's still a handy ability.

Jon
OK, thanks. I have also suspected that I may have some hardware
problem with my memory, because when I googled, I could not find a
whole lot info about this exception. Now back to multicast delegate.
When there are more than one ways to respond to a button click, why
can't we just put those ways in a single click event handler?
Jul 21 '08 #54
On Jul 21, 1:31*pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
On Mon, 21 Jul 2008 10:03:36 -0700, Author <gnewsgr...@gmail.comwrote:
[...]
I think the frustration comes from not understanding
what are the stuffs which the invoking method knows vs. what are the
stuffs which the invoking method does not know.

I feel your pain. *To some extent, it's a matter of experience. *You don't *
say how much programming experience you have, but in the simplest systems, *
this just doesn't come up at all. *But in more real-world situations, and *
especially in object-oriented programming, you start seeing code that *
depends on some implementation detail being done at some later time and/or *
by someone else.
If people don't use their real names in this group, you can get an
idea about their programming experience. :-)

The only real-world experience I've had with delegates is in event
handling. I have a little practice encapsulating methods with
delegates, but those use delegate for delegate's sake and don't help
me learn when, besides event handling, in the real world, I should use
a delegate.

There's more, scroll down please.
>
Virtual functions are an example of this, as are interfaces and abstract *
classes (two closely related concepts, which to some extent rely on the *
concept of virtual functions). *Function pointers are yet another, and *
delegates are the C# form of function pointers. *These all allow someone *
to write some code A that calls an implementation B that is, at the time *
that the code A is being written, does not exist or is otherwise unknown.

Until you've seen some actual examples (MSDN has a number of them, which *
you should be able to find by searching on terms and examples used in this *
thread), it can indeed be hard to really comprehend the use. *Once you've *
seen the examples and especially once you've been able to use the *
techniques yourself, they start to make more sense.
So, for example, in the following code,
Button b = new Button();
b.Text = "Click me";
b.Click += new System.EventHandler(b_Click);
we dynamically create a button control, and delegate its Click event
handler to b_Click method through newing System.EventHandler. *Does
this mean that
1. we want the Click event of the button to be handled,

Yes.
2. we don't know how it is gonna be handled,

yes.
3. if we know how the Click event should / will be handled, then we
simply code the logic at where "new System.EventHandler(b_Click)" is,
maybe through an anonymous method

No. *That is, yes...you could write an anonymous method. *But at the point *
you suggest, you would still be taking advantage of the polymorphic *
behavior of the delegate.
Thanks. Yes, in an environment where the b_Click event handler is
developed by a different developer, this event delegate makes good
sense to me. It seems that you implied that if I *do* know how the
Click event will be handled, I can code the logic on the right hand
side of b.Click += through a anonymous method block.
The _interesting_ part in the example you provided is the Click event *
itself, not the delegate used to subscribe to the event. *That is, *
consider where that event exists. *It's part of the Button class. *Now, *
who wrote the Button class? *Was it you? *No. *It was Microsoft.

When Microsoft wrote the Button class, did they know you were going to *
write a method named "b_Click" that would handle the Click event? *No, *
they didn't. *But because of the idea of an event and a delegate that can *
be subscribed to the event, they've provided a mechanism by which their *
own code, written long before you came along, can call your code without *
knowing anything specific about it at the time they wrote their code.

They define the signature of the method, and leave the rest up to you. *As *
long as you comply with the defined signature, you can have whatever code*
you want execute when the Click event is raised, and it just works.

Even though Microsoft didn't talk to you before they implemented and *
delivered the Button class to the world. *:)

Pete
Jul 21 '08 #55
On Mon, 21 Jul 2008 11:02:07 -0700, Author <gn********@gmail.comwrote:
[...]
Thanks. Yes, in an environment where the b_Click event handler is
developed by a different developer, this event delegate makes good
sense to me. It seems that you implied that if I *do* know how the
Click event will be handled, I can code the logic on the right hand
side of b.Click += through a anonymous method block.
No, that wasn't my intent. There's not much difference between:

class SomeClass
{
void SomeMethod()
{
Button b = new Button();

b.Click += delegate(object sender, EventArgs e) { // some code
here };
}
}

and:

class SomeClass
{
void SomeMethod()
{
Button b = new Button();

b.Click += b_Click;
}

void b_Click(object sender, EventArgs e)
{
// some code here
}
}

That is, in either case, the implementation is in fact known, and it is in
fact encapsulated in the given class. The anonymous method winds up in
SomeClass, just like the named method b_Click() does. It just doesn't
have a name (hence "anonymous").

The point is that the handler itself, written by you (whether as an
anonymous method or a named method), is not known at the time that the
_Button_ class was written (by Microsoft in this case, but you can write
classes with your own events and other forms of polymorphism as well of
course).

Pete
Jul 21 '08 #56
raylopez99 <ra********@yahoo.comwrote:
On Jul 21, 4:41*am, "Jon Skeet [C# MVP]" <sk...@pobox.comwrote:
Again, code would be helpful. I suspect that when you say "a class
declared in the parent form" you mean "a variable declared in the
parent form" but I don't even know whether you mean "parent" in an
inheritance sense or not.
Jon Skeet--here is the code.
Well, that's part of the code. You've not included the designer files,
which contain InitializeComponent. This is why I usually use console
apps for examples - they're much simpler. The principles are the same
though.
I think the problem is much more basic:
I don't know how different forms exist in the namespace.
Well, that's *one* problem - but it's not the reason for the compiler
complaining. The forms are just classes like Class1 and class2.
See the comment at "***" below. I assumed they shared the same
classes, but they don't.
That depends on what you mean by "shared".
I will wait one or two days and check for an answer here, and, if no
answer, I'll make this a separate thread since it's really not so much
a delegate/event question but a namespace/scope question.
Have I ever taken two days to answer you? :)

The reason your code didn't compile was that the variable was private
in the base class. Here's a short but complete example demonstrating
it, without involving a GUI or any more classes than we really need.

using System;

class Base
{
private string privateBaseField = "1";
public string publicBaseField = "2";
}

class Derived : Base
{
private string privateDerivedField = "3";
private string publicDerivedField = "4";

public void Foo()
{
// Illegal
// string a = privateBaseField;
string b = publicBaseField;
string c = privateDerivedField;
string d = publicDerivedField;
}

// Just keep the compiler happy for a console app
static void Main() {}
}

Now, running this program won't actually do anything, but look inside
the Foo method. It has access to privateDerivedField because that's
declared in the same class as Foo - but it *doesn't* have access to
privateBaseField because that's declared in Base. It has access to both
publicDerivedField and publicBaseField because they're public.

There are various other access modifiers - look them up in Nutshell for
the details.

Does that help?

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jul 21 '08 #57
Author <gn********@gmail.comwrote:

<snip>
I struggle to understand "code that wants to be able to execute some
arbitrary code without knowing what that code is at compile time".

Marc also says in the 2nd post of this thread that "Delegates become
useful when the code that invokes them cannot possibly know about the
actual methods (such as List<T>.Find)", which, too, I struggle to
understand.
<snip>

It does take a while to really grok it, but it's important stuff -
particularly for LINQ. I'll explain it using List<T>.Find as an
example, as then we don't need to include any events, which complicate
things a bit.

Let's suppose we were implementing List<Tourselves. We want to write
the Find method, which is going to find an element. What element is it
going to find though? Well, we could take a parameter of type T, and
then call Equals on each element in the list to see if it's the same as
the one being passed in. That's not really useful though. What would be
more useful would be to be able to pass something else which somehow
specified what we wanted to find - something which could look at each
element and say whether or not it was the right one. That's exactly
what the Predicate<Tdelegate is for. Here's the signature:

public delegate bool Predicate<T>(T obj)

So, any instance of Predicate<Tis some code which can take an object
of type T, and return a Boolean when it's finished processing, to say
whether or not it "matches" the delegate.

With that in place, List<T>.Find is simple. All we need to do is loop
through all the elements, call the specified predicate on each element,
and if it returns true, return that element. If none of them do, we'll
return the default value for T. Here's an example implementation:

public void Find(Predicate<Tpredicate)
{
// "this" is the list
foreach (T element in this)
{
// Test the current element against the predicate
if (predicate(element)
{
// Success! Return the element
return element;
}
}

// Didn't match anything.
return default(T);
}

So, that's the side which will call the predicate. Now we've got to
provide the predicate when we call Find. C# 2 and 3 make this a lot
easier, as shown here:

using System;
using System.Collections.Generic;

class Test
{
static readonly string[] Names =
{"Jon", "Pete", "Ray", "Author", "Bill", "Marc"};

static void Main()
{
List<stringlist = new List<string>(Names);

// C# 1 syntax (apart from generics!)
string fourLetters = list.Find
(new Predicate<string>(MatchFourLetters));

// C# 2 syntax - anonymous method
string beginsWithA = list.Find(delegate(string x)
{ return x.StartsWith("A"); }
);

// C# 3 syntax - lambda expression
string endsWithY = list.Find(x =x.EndsWith("y"));
Console.WriteLine(fourLetters);
Console.WriteLine(beginsWithA);
Console.WriteLine(endsWithY);
}

static bool MatchFourLetters(string text)
{
return text.Length == 4;
}
}

Notice how the "searching" part is implemented in List<T>, but the
"what to search for" part is specified in the test code - and it's very
flexible, as we've shown here.

Here's another look at the same kind of thing:
http://csharpindepth.com/Articles/Ch.../Closures.aspx

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jul 21 '08 #58
Author <gn********@gmail.comwrote:
OK, thanks. I have also suspected that I may have some hardware
problem with my memory, because when I googled, I could not find a
whole lot info about this exception. Now back to multicast delegate.
When there are more than one ways to respond to a button click, why
can't we just put those ways in a single click event handler?
They could come from completely different pieces of code which don't
know about each other. One piece of code might be capturing all events
to send back to the user experience team, another piece of code might
be actually acting on the button click (e.g. to save a document).

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jul 21 '08 #59
On Jul 21, 11:18*am, Jon Skeet [C# MVP] <sk...@pobox.comwrote:
Does that help?

-
No. It doesn't work. What is going on is more complicated than that,
unfortunately, but thanks for trying. What you need is a forward
reference outside the class normal constructor, but even then you
cannot access the Form1's classes. Something must be going on behind
the scenes depending on how the rest of the 'partial class' works.
Try this in Forms GUI, not console mode,and perhaps you'll see. I
have nothing against what you say in theory--but that's not the way
these forms are working (non-console mode).

I reproduce below and emphasize what I'm talking about with the
symbol /*!*/. BTW I made all the classes public, all the members
public (so they are working effectively as structures and you still
cannot 'see', using the InteliSense tool, the classes in the other
form).

Here's a quick tip (cause I have to go now)...try this yourself and
just see if you can reference, from a child form, a class declared in
the parent.

RL

public partial class Form1 : Form
{
Class1 myClass1; /*!*/ //THIS IS KNOWN AS A FORWARD REFERENCE
IN C++, AND IT ALLOWS YOU TO 'SEE' CLASS1 in the Normal constructor
below, but that''s just PART of the problem. The other problem is you
CANNOT, no matter what, 'see' any such instantiated class in Form 2
which is a child of main form, Form 1--RL

public Form1()
{
InitializeComponent();
myClass1 = new Class1(100, "hello1"); /*!*/ //BUT FOR THE
FORWARD REFERENCE ABOVE, YOU CANNOT EVEN INSTANTIATE HERE...BUT AGAIN,
THAT'S JUST HALF THE PROBLEM.
}
public int myForm1Method()
{
// myClass1 seen here
return 1;
}

////////
Public partial class Form2 : Form
{
Class2 myClass2;
Class1 myNewClass1;
public Form2()
{
InitializeComponent();
myClass2 = new Class2();
myNewClass1 = new Class1(99, "helloagain1");
public int myForm2Method()
{
//***myClass2 seen here, myNewClass1 seen here, but 'myClass1' not
seen here.

*/!*/ // THIS IS KEY. READ THE ABOVE COMMENT. YOU CANNOT SEE
myClass1 in this form, child form Form2. EVEN IF YOU CHANGE it to
"Public partial class Form2 : Form1" //<--NOTE THE INHEREITANCE HAS
CHANGED.
//This is true even if Form2:Form1, and if 'public' added to
classes 1, 2. Why is that?
return 2;
}

}
//////////////
//Class1, class 2 are basically the same //deleted.
Again, a simple example where you can, using simple Windows forms,
'see' a class declared in a parent base form in the form that is a
child, would be helpful. I don't think I played with the "Properties"
to make this impossible, but, if you've seen this problem before
(playing with the properties will make a child form 'private' and/or
parent form 'private' so nothing can be 'seen' by any other form),
please let me know.

Thanks, gotta run...

Ray
Jul 21 '08 #60
On Jul 21, 12:08*pm, raylopez99 <raylope...@yahoo.comwrote:
>
Again, a simple example where you can, using simple Windows forms,
'see' a class declared in a parent base form in the form that is a
child, would be helpful. *I don't think I played with the "Properties"
to make this impossible, but, if you've seen this problem before
(playing with the properties will make a child form 'private' and/or
parent form 'private' so nothing can be 'seen' by any other form),
please let me know.

Thanks, gotta run...

OK, back again. I was thinking about this over dinner, and concluded
that the solution lies with passing information by way of a
parametricized constructor rather than a default normal constructor.

And sure enough that worked.

Simple example: if you want to pass class1 from the parent form to
the child form, you do this, from inside of Form1 (the parent form):

Form2 frm2 = new Form2(myClass1);
frm2.Show();

// you do not do this:

//won't work
// Form2 frm2 = new Form2(); //normal, unparametized constructor will
not work
// frm2.Show();

That simple..now Class1 myClass1 is 'seen' in Form2, no problem.

I'll post on a separate thread, and reserve the right to make fun of
you, Jon Skeet, for not catching such an obvious thing. What KIND of
a C# programmer are you? Just kidding...I'll keep the sarcasm to a
minimum, but, honestly (not really) what were you thinking Jon Skeet?

RL
Jul 21 '08 #61
raylopez99 <ra********@yahoo.comwrote:
Does that help?

No. It doesn't work. What is going on is more complicated than that,
unfortunately, but thanks for trying.
Actually the problem is *exactly* the one I showed in the code sample.
You're making it more complicated by involving partial classes, forms,
and Class1/Class2, but the core of the problem is the same thing:
you're trying to access a private variable in a base class from a
derived class, and you just can't do that.
What you need is a forward
reference outside the class normal constructor, but even then you
cannot access the Form1's classes.
There's no such thing as a forward reference in C#.

What you've labeled as a forward reference in your sample source code
is actually declaring a variable.
Something must be going on behind
the scenes depending on how the rest of the 'partial class' works.
Try this in Forms GUI, not console mode,and perhaps you'll see. I
have nothing against what you say in theory--but that's not the way
these forms are working (non-console mode).

I reproduce below and emphasize what I'm talking about with the
symbol /*!*/. BTW I made all the classes public, all the members
public (so they are working effectively as structures and you still
cannot 'see', using the InteliSense tool, the classes in the other
form).
No, you haven't made all the members public:

public partial class Form1 : Form
{
Class1 myClass1;

That's declared a *private* variable.

If you change it to:

public partial class Form1 : Form
{
public Class1 myClass1;

then you'll be able to see it where you were complaining.
Here's a quick tip (cause I have to go now)...try this yourself and
just see if you can reference, from a child form, a class declared in
the parent.
Once again, you don't declare a *class* in the parent (leaving nested
types aside). You declare a *variable* in the parent. That's what
you've done in the code quoted above, but you've declared it as a
private variable. That means the child classes can't access it.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jul 21 '08 #62
raylopez99 <ra********@yahoo.comwrote:
OK, back again. I was thinking about this over dinner, and concluded
that the solution lies with passing information by way of a
parametricized constructor rather than a default normal constructor.
No, it's got nothing to do with that. You may have come up with a
workaround, but if you still don't understand what was going on you're
going to be twisting your code all over the place for no reason.
And sure enough that worked.

Simple example: if you want to pass class1 from the parent form to
the child form, you do this, from inside of Form1 (the parent form):

Form2 frm2 = new Form2(myClass1);
frm2.Show();

// you do not do this:

//won't work
// Form2 frm2 = new Form2(); //normal, unparametized constructor will
not work
// frm2.Show();

That simple..now Class1 myClass1 is 'seen' in Form2, no problem.
Not if you're still trying to refer to a *private* myClass1 variable
from a different class.
I'll post on a separate thread, and reserve the right to make fun of
you, Jon Skeet, for not catching such an obvious thing. What KIND of
a C# programmer are you? Just kidding...I'll keep the sarcasm to a
minimum, but, honestly (not really) what were you thinking Jon Skeet?
I was thinking, and I'm *still* thinking, that you don't really
understand the problem properly.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jul 21 '08 #63
raylopez99 <ra********@yahoo.comwrote:

Just rereading your code - look closely:
////////
Public partial class Form2 : Form
{
Class2 myClass2;
Class1 myNewClass1;
public Form2()
{
InitializeComponent();
myClass2 = new Class2();
myNewClass1 = new Class1(99, "helloagain1");
public int myForm2Method()
{
//***myClass2 seen here, myNewClass1 seen here, but 'myClass1' not
seen here.

*/!*/ // THIS IS KEY. READ THE ABOVE COMMENT. YOU CANNOT SEE
myClass1 in this form, child form Form2. EVEN IF YOU CHANGE it to
"Public partial class Form2 : Form1" //<--NOTE THE INHEREITANCE HAS
CHANGED.
//This is true even if Form2:Form1, and if 'public' added to
classes 1, 2. Why is that?
return 2;
}
That code is trying to declare a method inside the constructor. I
strongly suspect that *isn't* the code you had. I really hope it isn't,
anyway.

Once again, if you could post *complete* code (i.e. avoid partial
classes and forms - they really are irrelevant to your problem) you
would make your life a lot easier.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jul 21 '08 #64
On Jul 21, 9:46*pm, Author <gnewsgr...@gmail.comwrote:
OK, thanks. *I have also suspected that I may have some hardware
problem with my memory, because when I googled, I could not find a
whole lot info about this exception. *Now back to multicast delegate.
When there are more than one ways to respond to a button click, why
can't we just put those ways in a single click event handler?
Mostly because those "ways" might not even know about each other. This
becomes obvious really soon if you do GUI programming using the
Observer pattern - i.e., you don't just have event handlers subscribed
to buttons etc to handle user input, but you also have event handlers
subscribed to PropertyChanged event (or similar) on your business
object to dynamically update GUI as model changes.

If it's still unclear, that's alright. I can actually explain it on a
real-world example. Consider a GUI application which edits a tree of
objects. On the left of it is the actual TreeView control that
displays the hierarchy; labels represent Name property of the objects
in the tree. On the right is a panel which has different content
depending on the kind of the element currently selected in the tree,
but which usually includes a textbox to edit Name. The user can also
edit names directly in the tree, by click-pause-click as it usually
works in Windows. And, of course, we want the tree and the textbox to
stay in sync always - if one is updated, so should be the other.

Now, you can, of course, update the tree from the TextBox.TextChanged
handler, and update the textbox from the TreeView.AfterLabelEdit event
handler. But, as more and more controls that should stay in sync are
added, the more code you have to add to all handlers, and the more
entwined logically different parts of your application become (in the
real-world program, there was also a preview window that had to be
refreshed, and "Save" button on the toolbar that tracked changes to
enable/disable itself depending on whether there was anything to
save).

On the other hand, a much simpler approach is to let every distinct
part just change the business object on user input, without concerning
itself about propagating changes to the rest of UI. To do the latter,
every control that needs to be aware of the changes subscribes to
PropertyChanged event of the business object. Note that in this
scenario, we have several event handlers on the same event of the same
object which do not know anything about each other (nor should they,
really) - all components are truly separate, and can be reused and
refactored each on its own. Yet the end result is a complex system
working in unison - as user inputs text in the textbox, the Name
property of the object is updated, which causes PropertyChange event,
which in turn updates the tree, the toolbar, the preview window, and
the rest of it. And furthermore, adding a new change-aware control
does not require you to change the code for any existing ones.
Jul 21 '08 #65
Jon Skeet [ C# MVP ] wrote:
Author <gn********@gmail.comwrote:

<snip>
I struggle to understand "code that wants to be able to execute some
arbitrary code without knowing what that code is at compile time".

Marc also says in the 2nd post of this thread that "Delegates become
useful when the code that invokes them cannot possibly know about the
actual methods (such as List<T>.Find)", which, too, I struggle to
understand.

<snip>

It does take a while to really grok it, but it's important stuff -
particularly for LINQ. I'll explain it using List<T>.Find as an
example, as then we don't need to include any events, which complicate
things a bit.

Let's suppose we were implementing List<Tourselves. We want to write
the Find method, which is going to find an element. What element is it
going to find though? Well, we could take a parameter of type T, and
then call Equals on each element in the list to see if it's the same as
the one being passed in. That's not really useful though. What would be
more useful would be to be able to pass something else which somehow
specified what we wanted to find - something which could look at each
element and say whether or not it was the right one. That's exactly
what the Predicate<Tdelegate is for. Here's the signature:

public delegate bool Predicate<T>(T obj)

So, any instance of Predicate<Tis some code which can take an object
of type T, and return a Boolean when it's finished processing, to say
whether or not it "matches" the delegate.

With that in place, List<T>.Find is simple. All we need to do is loop
through all the elements, call the specified predicate on each element,
and if it returns true, return that element. If none of them do, we'll
return the default value for T. Here's an example implementation:

public void Find(Predicate<Tpredicate)
{
// "this" is the list
foreach (T element in this)
{
// Test the current element against the predicate
if (predicate(element)
{
// Success! Return the element
return element;
}
}

// Didn't match anything.
return default(T);
}

So, that's the side which will call the predicate. Now we've got to
provide the predicate when we call Find. C# 2 and 3 make this a lot
easier, as shown here:

using System;
using System.Collections.Generic;

class Test
{
static readonly string[] Names =
{"Jon", "Pete", "Ray", "Author", "Bill", "Marc"};

static void Main()
{
List<stringlist = new List<string>(Names);

// C# 1 syntax (apart from generics!)
string fourLetters = list.Find
(new Predicate<string>(MatchFourLetters));

// C# 2 syntax - anonymous method
string beginsWithA = list.Find(delegate(string x)
{ return x.StartsWith("A"); }
);

// C# 3 syntax - lambda expression
string endsWithY = list.Find(x =x.EndsWith("y"));
Console.WriteLine(fourLetters);
Console.WriteLine(beginsWithA);
Console.WriteLine(endsWithY);
}

static bool MatchFourLetters(string text)
{
return text.Length == 4;
}
}

Notice how the "searching" part is implemented in List<T>, but the
"what to search for" part is specified in the test code - and it's very
flexible, as we've shown here.

Here's another look at the same kind of thing:
http://csharpindepth.com/Articles/Ch.../Closures.aspx

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Thank you very much. I think this Find example is enlightening. Most
of the time, we see delegate examples that are related to event
handling or they are for delegate's sake, giving us a false impression
that delegates are for event handling only.

I think the delegate philosophy seems to be clear now: We use a
delegate

1. when we don't know or it is impossible for us to know how a
certain part of an application is to be implemented, or

2. we know of a bunch of different potential ways to approach it, but
instead of trying to implement all possibilities and cluttering our
code with switches or ifs and maybe additional argument into the
method signature, we give (hence delegate) the concrete task to the
consumer class.
Jul 22 '08 #66
raylopez99 <ra********@yahoo.comwrote:
Jon Skeet--here is the code. I think the problem is much more basic:
I don't know how different forms exist in the namespace. See the
comment at "***" below. I assumed they shared the same classes, but
they don't.
I've just spotted something I hadn't seen before, which makes my sample
code somewhat less useful. You'd said that Form2 derived from Form1 -
but in your code, they both just derive from Form.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jul 22 '08 #67
Author <gn********@gmail.comwrote:
Thank you very much. I think this Find example is enlightening. Most
of the time, we see delegate examples that are related to event
handling or they are for delegate's sake, giving us a false impression
that delegates are for event handling only.
Not only that, but people also get confused as to what an event
actually is. It's just a pair of methods - add and remove - linked by
some metadata.
I think the delegate philosophy seems to be clear now: We use a
delegate

1. when we don't know or it is impossible for us to know how a
certain part of an application is to be implemented, or

2. we know of a bunch of different potential ways to approach it, but
instead of trying to implement all possibilities and cluttering our
code with switches or ifs and maybe additional argument into the
method signature, we give (hence delegate) the concrete task to the
consumer class.
Yup. And of course 2 is just a special case of 1, really.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jul 22 '08 #68
On Jul 22, 1:19*am, Jon Skeet [C# MVP] <sk...@pobox.comwrote:
Author <gnewsgr...@gmail.comwrote:
Thank you very much. *I think this Find example is enlightening. Most
of the time, we see delegate examples that are related to event
handling or they are for delegate's sake, giving us a false impression
that delegates are for event handling only.

Not only that, but people also get confused as to what an event
actually is. It's just a pair of methods - add and remove - linked by
some metadata.
I think the delegate philosophy seems to be clear now: *We use a
delegate
1. *when we don't know or it is *impossible for us to know how a
certain part of an application is to be implemented, or
2. we know of a bunch of different potential ways to approach it, but
instead of trying to implement all possibilities and cluttering our
code with switches or ifs and maybe additional argument into the
method signature, we give (hence delegate) the concrete task to the
consumer class.

Yup. And of course 2 is just a special case of 1, really.
That's right, I thought about this, too. Actually thought about making
this point. As a matter a fact, event handling is also only a special
case of delegate usage.
>
--
Jon Skeet - <sk...@pobox.com>
Web site:http://www.pobox.com/~skeet*
Blog:http://www.msmvps.com/jon.skeet
C# in Depth:http://csharpindepth.com
Jul 22 '08 #69
Author <gn********@gmail.comwrote:
Yup. And of course 2 is just a special case of 1, really.

That's right, I thought about this, too. Actually thought about making
this point. As a matter a fact, event handling is also only a special
case of delegate usage.
Absolutely. Open your mind to the possibilities of doing other things
:)

It sounds like you've got a *much* better handle on delegates now.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jul 22 '08 #70

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.