C# event inheritance
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] F开发者_如何学Pythonound 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.
The code
if (SomethingChanged != null)
SomethingChanged(this);
(which has a race-condition, by the way) implies calling Delegate.GetInvocationList
on SomethingChanged
. 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.
Use:
this.SomethingChanged += new One.del(one_SomethingChanged);
精彩评论