Reputation: 4157
never came across this before. Here's the sample:
using System;
namespace Testing
{
public class Test
{
public event Action ActionRequired;
}
public class ChildTest : Test
{
public void DoSomething()
{
if (this.ActionRequired != null)
this.ActionRequired();
}
}
}
This won't work, the error being I can only access the event from the base class.
It's not difficult to sail around (add a protected method to the base class that does both check an invocation of the event and call that method from the child classes), but I really wonder what's the idea behind this restriction?
Cheers,
Sebi
Upvotes: 6
Views: 6500
Reputation: 4066
As per previous answer added by @ThomasLevesque https://stackoverflow.com/a/4742280/3926461
you can declare your action without using this syntactic sugar Like the below:
public class Test
{
protected Action _actionRequired;
public event Action ActionRequired {
add {
_actionRequired += value;
}
remove {
_actionRequired += value;
}
}
}
public class ChildTest : Test
{
public void DoSomething()
{
if (this._actionRequired != null)
this._actionRequired();
}
}
Upvotes: 1
Reputation: 124632
You cannot invoke events from outside of the class within which they were defined. However, you don't need to; just follow the idiomatic patter of also declaring a protected method to fire said event.
class Whatever
{
public event EventHandler Foo;
protected virtual void OnFoo( EventArgs e )
{
EventHandler del = Foo;
if( del != null )
{
del( this, e );
}
}
}
Now descendants of class "Whatever" can fire the event by calling OnFoo() and passing in the appropriate EventArgs object.
EDIT: In regards to why this is the behavior, Jon Skeet explained it well in another thread (which also means that this question is a duplicate, so voting to close):
When you declare a public field-like event, the compiler creates a public event, and a private field. Within the same class (or nested classes) you can get at the field directly, e.g. to invoke all the handlers. From other classes, you only see the event, which only allows subscription and unsubscription.
Upvotes: 14
Reputation: 292355
The syntax you used to declare the event in your example is actually syntactic sugar for something like this:
private Action _actionRequired;
public event Action ActionRequired
{
add { _actionRequired += value; }
remove { _actionRequired -= value }
}
(the actual code is a little more complex of course)
The important part here is that the _actionRequired
field is private. Only the event itself is public, but it's only a pair of add/remove methods (similar to a property). So the only thing you can do with the event is subscribe to or unsubscribe from it. The field that hold the actual delegate is private, so it can only be accessed from the class that declares it. When you use ActionRequired
in the class that declares it, it refers either to the delegate field or the event itself, depending on the context.
But from any other class, only the event is accessible, not the field. That's why you can't invoke the delegate from another class, even a derived class.
Upvotes: 3