Events in C#

G

Guest

When I override the 'add' and 'remove' methods for an event, why can't I
invoke it ? The sample code is provided below - I have two events - 'my' and
'ev' - while invoking, my() works but ev() does not ! The compiler complains
that : The event "'Blog.EventsvsDelegates.Form1.ev' can only appear on the
left hand side of += or -="

Why ?

public delegate void MyEvent();
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private event MyEvent my;

private event MyEvent pvt_ev;
public event MyEvent ev
{
add
{
pvt_ev +=value;
}

remove
{
pvt_ev-=value;
}
}

public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

my+=new MyEvent(this.Test);
my+=new MyEvent(this.Test1);

ev+=new MyEvent (this.Test );
}

protected void Test()
{
MessageBox.Show ("Test");
}

protected void Test1()
{
MessageBox.Show ("Test1");
}

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}

private void button1_Click(object sender, System.EventArgs e)
{
my(); // WORKS
//ev (); //DOES NOT WORK
}

}
 
L

Larry Lard

pSm said:
When I override the 'add' and 'remove' methods for an event, why can't I
invoke it ? The sample code is provided below - I have two events - 'my' and
'ev' - while invoking, my() works but ev() does not ! The compiler complains
that : The event "'Blog.EventsvsDelegates.Form1.ev' can only appear on the
left hand side of += or -="

Why ?

The help page for this error (CS0079) includes a sample very similar to
yours that shows you exactly what to do. I found this out by reproducing
your sample then hitting F1 with the error selected...
 
G

Guest

Thanks Larry.

But this does not really answer my question ! Why does the compiler restrict
the invocation ?
 
J

Jon Skeet [C# MVP]

pSm said:
When I override the 'add' and 'remove' methods for an event, why can't I
invoke it ? The sample code is provided below - I have two events - 'my' and
'ev' - while invoking, my() works but ev() does not ! The compiler complains
that : The event "'Blog.EventsvsDelegates.Form1.ev' can only appear on the
left hand side of += or -="

And it's right. An event is really just an add/remove pair of methods.
(There's also raise, but that doesn't get exposed in C#.) When you
declare a field-like event, that's really declaring both the event
*and* a delegate. When you access the name within the class, it refers
to the delegate. When you access the name outside the class, it refers
to the event. Delegates can be invoked - events can't.
 
L

Lloyd Dupont

And it's right. An event is really just an add/remove pair of methods.
(There's also raise, but that doesn't get exposed in C#.) When you

No, there is no such thing as "raise"!
Events are stored as multicast delegates and used as such.
declare a field-like event, that's really declaring both the event
*and* a delegate. When you access the name within the class, it refers
to the delegate. When you access the name outside the class, it refers
to the event. Delegates can be invoked - events can't.

Well events are just delegate, and of course they could be ".Invoke(..)", as
any other delegate.
But a semantic akin to private/protect/public prevent to do it from anywhere
but the declaring class itself.
 
L

Lloyd Dupont

give pvt_ev a public accessor.
otherwise it's quite obvious, if you have no access to it, how could you
hope invoke it?!?!
 
G

Guest

Lloyd,
Why would pvt_ev() need a public accessor when I invoke it from the same
class ? In fact any 'event' that is declared as public, would be converted to
'private' by the compiler - events can never be invoked from outside it's
class.

I was checking the MSIL and noticed that when 'add' and 'remove' accessors
are declared, the ev declaration is removed, and so invoke on ev() no longer
works.

I had posted this question on GOTDOTNET discussion forum too and I think
Alan came close to answering why the compiler does not allow invoking ev().

You can read the whole story here : <a
href="http://blogs.ittoolbox.com/visualbasic/operating/archives/events-vs-delegates-contd-10596">Events vs Delegates </a>

Lloyd Dupont said:
give pvt_ev a public accessor.
otherwise it's quite obvious, if you have no access to it, how could you
hope invoke it?!?!

pSm said:
When I override the 'add' and 'remove' methods for an event, why can't I
invoke it ? The sample code is provided below - I have two events - 'my'
and
'ev' - while invoking, my() works but ev() does not ! The compiler
complains
that : The event "'Blog.EventsvsDelegates.Form1.ev' can only appear on the
left hand side of += or -="

Why ?

public delegate void MyEvent();
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private event MyEvent my;

private event MyEvent pvt_ev;
public event MyEvent ev
{
add
{
pvt_ev +=value;
}

remove
{
pvt_ev-=value;
}
}

public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

my+=new MyEvent(this.Test);
my+=new MyEvent(this.Test1);

ev+=new MyEvent (this.Test );
}

protected void Test()
{
MessageBox.Show ("Test");
}

protected void Test1()
{
MessageBox.Show ("Test1");
}

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}

private void button1_Click(object sender, System.EventArgs e)
{
my(); // WORKS
//ev (); //DOES NOT WORK
}

}
 
J

Jon Skeet [C# MVP]

Lloyd said:
No, there is no such thing as "raise"!
Events are stored as multicast delegates and used as such.

C# doesn't expose it, but it's part of the .NET event system.
See CLI spec partition 1 section 10.4.
Well events are just delegate, and of course they could be ".Invoke(..)", as
any other delegate.

No, events aren't delegates any more than properties are variables. An
event is solely a set of appropriately decorated methods. It's possible
(although it would be very odd) to implement an event without actually
storing a delegate. You'd need to store pretty much the same
information, but the only ways in which events are intrinsically linked
to delegates are:

1) C#'s field-like event support, which declares a delegate variable
and an event
2) the signatures of event methods.
But a semantic akin to private/protect/public prevent to do it from anywhere
but the declaring class itself.

Events only have add/remove semantics, along with the raise as
mentioned before. Whether they are implemented by having a delegate
variable is an implementation matter. Some implementations keep the
delegates for all events in a hashtable, so that you don't need a
variable per event where there are lots of events which may not be
subscribed to at all.

Jon
 
L

Lloyd Dupont

Why would pvt_ev() need a public accessor when I invoke it from the same
Sorry, I misread your sample.
just change:to
private void button1_Click(object sender, System.EventArgs e)
{
pvt_ev ();
}

In fact any 'event' that is declared as public, would be converted to
'private' by the compiler - events can never be invoked from outside it's
class.

I was checking the MSIL and noticed that when 'add' and 'remove' accessors
are declared, the ev declaration is removed, and so invoke on ev() no
longer
works.

I had posted this question on GOTDOTNET discussion forum too and I think
Alan came close to answering why the compiler does not allow invoking
ev().

You can read the whole story here : <a
href="http://blogs.ittoolbox.com/visualbasic/operating/archives/events-vs-delegates-contd-10596">Events
vs Delegates </a>

Lloyd Dupont said:
give pvt_ev a public accessor.
otherwise it's quite obvious, if you have no access to it, how could you
hope invoke it?!?!

pSm said:
When I override the 'add' and 'remove' methods for an event, why can't
I
invoke it ? The sample code is provided below - I have two events -
'my'
and
'ev' - while invoking, my() works but ev() does not ! The compiler
complains
that : The event "'Blog.EventsvsDelegates.Form1.ev' can only appear on
the
left hand side of += or -="

Why ?

public delegate void MyEvent();
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private event MyEvent my;

private event MyEvent pvt_ev;
public event MyEvent ev
{
add
{
pvt_ev +=value;
}

remove
{
pvt_ev-=value;
}
}

public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

my+=new MyEvent(this.Test);
my+=new MyEvent(this.Test1);

ev+=new MyEvent (this.Test );
}

protected void Test()
{
MessageBox.Show ("Test");
}

protected void Test1()
{
MessageBox.Show ("Test1");
}

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}

private void button1_Click(object sender, System.EventArgs e)
{
my(); // WORKS
//ev (); //DOES NOT WORK
}

}
 
L

Lloyd Dupont

Oops,
I think I misread you anyway.
It was more of a phylosophical debate rather than a practical question.
Dimiss my previous answer....
 

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