I have this program:
class One
{
public delegate void del(object o);
public event del SomethingChanged;
int x;
public int X
{
get { return x; }
set { x = value; OnSomethingChanged(this); }
}
protected void OnSomethingChanged(object o)
{
if (SomethingChanged != null)
SomethingChanged(o);
}
}
class Two: One
{
public void ChangeSomething()
{
//if (SomethingChanged != null)
// SomethingChanged(this);
OnSomethingChanged(this);
}
}
static void Main(string[] args)
{
One one = new One();
Console.WriteLine(one.X);
one.SomethingChanged += new One.del(one_SomethingChanged);
one.X = 5;
}
static void one_SomethingChanged(object o)
{
Console.WriteLine(((One)o).X);
}
There are 2 classes - One and Two, Two is descendant of One. There is event declared in class One(SomethingChanged) and it is triggered by class One and class Two. But take a look at Two.ChangeSomething - it raises event by invoking base class's method. However if I try to invoke event using raw code like
if (SomethingChanged != null) SomethingChanged(this);
I'm getting compiler error saying
The event 'One.SomethingChanged' can only appear on the left hand side of += or -= (except when used from within the type 'eventstest.Program.One')
So I'm just curious why I can't use 'raw' code in class Two to raise event but when I invoke a corresponding function event gets raised?
[EDIT] Found some clarification here: C#: Raising an inherited event
When you declare an event using the "event" keyword in C#, the generated IL actually contains two corresponding elements: a private delegate field and an event accessor with the same visibility as the declared event. The event accessor cannot be used to fire the event. It is only used to subscribe and unsubscribe from notifications. Your
SomethingChanged(this)
code is using the private field to invoke the delegate, and that private field is not available from outside the class.Use:
The code
(which has a race-condition, by the way) implies calling
Delegate.GetInvocationList
onSomethingChanged
. Automatically implemented events don't allow you to do that unless you are in the class the event is defined in.You would be able to do it if you implemented the event manually and provided
protected
access to the delegate field backing the event.Have a look at Use event and delegate in subclass.