C#:引发继承的事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/756237/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C#: Raising an inherited event
提问by jwarzech
I have a base class that contains the following events:
我有一个包含以下事件的基类:
public event EventHandler Loading;
public event EventHandler Finished;
In a class that inherits from this base class I try to raise the event:
在从这个基类继承的类中,我尝试引发事件:
this.Loading(this, new EventHandler()); // All we care about is which object is loading.
I receive the following error:
我收到以下错误:
The event 'BaseClass.Loading' can only appear on the left hand side of += or -= (BaseClass')
事件 'BaseClass.Loading' 只能出现在 += 或 -= (BaseClass') 的左侧
I am assuming I cannot access these events the same as other inherited members?
我假设我不能像其他继承成员一样访问这些事件?
采纳答案by Frederik Gheysels
What you have to do , is this:
你必须做的是:
In your base class (where you have declared the events), create protected methods which can be used to raise the events:
在您的基类(您已在其中声明事件)中,创建可用于引发事件的受保护方法:
public class MyClass
{
public event EventHandler Loading;
public event EventHandler Finished;
protected virtual void OnLoading(EventArgs e)
{
EventHandler handler = Loading;
if( handler != null )
{
handler(this, e);
}
}
protected virtual void OnFinished(EventArgs e)
{
EventHandler handler = Finished;
if( handler != null )
{
handler(this, e);
}
}
}
(Note that you should probably change those methods, in order to check whether you have to Invoke the eventhandler or not).
(请注意,您可能应该更改这些方法,以检查是否必须调用事件处理程序)。
Then, in classes that inherit from this base class, you can just call the OnFinished or OnLoading methods to raise the events:
然后,在从该基类继承的类中,您可以调用 OnFinished 或 OnLoading 方法来引发事件:
public AnotherClass : MyClass
{
public void DoSomeStuff()
{
...
OnLoading(EventArgs.Empty);
...
OnFinished(EventArgs.Empty);
}
}
回答by Konrad Rudolph
I am assuming I cannot access these events the same as other inherited members?
我假设我不能像其他继承成员一样访问这些事件?
Precisely. It's customary to provide a protected function OnXyz
or RaiseXyz
for each event in the base class to enable raising from inherited classes. For example:
恰恰。习惯上提供一个受保护的函数OnXyz
或RaiseXyz
为基类中的每个事件启用从继承的类中提升。例如:
public event EventHandler Loading;
protected virtual void OnLoading() {
EventHandler handler = Loading;
if (handler != null)
handler(this, EventArgs.Empty);
}
Called in the inherited class:
在继承的类中调用:
OnLoading();
回答by Adam Robinson
You can only access an event in the declaring class, as .NET creates private instance variables behind the scenes that actually hold the delegate. Doing this..
您只能访问声明类中的事件,因为 .NET 在实际持有委托的幕后创建私有实例变量。这样做..
public event EventHandler MyPropertyChanged;
is actually doing this;
实际上是这样做的;
private EventHandler myPropertyChangedDelegate;
public event EventHandler MyPropertyChanged
{
add { myPropertyChangedDelegate += value; }
remove { myPropertyChangedDelegate -= value; }
}
and doing this...
并且这样做...
MyPropertyChanged(this, EventArgs.Empty);
is actually this...
其实这是……
myPropertyChangedDelegate(this, EventArgs.Empty);
So you can (obviously) only access the private delegate instance variable from within the declaring class.
因此,您(显然)只能从声明类中访问私有委托实例变量。
The convention is to provide something like this in the declaring class..
约定是在声明类中提供类似的东西..
protected virtual void OnMyPropertyChanged(EventArgs e)
{
EventHandler invoker = MyPropertyChanged;
if(invoker != null) invoker(this, e);
}
You can then call OnMyPropertyChanged(EventArgs.Empty)
from anywhere in that class or below the inheritance heirarchy to invoke the event.
然后,您可以OnMyPropertyChanged(EventArgs.Empty)
从该类中的任何位置或继承层次结构下的任何位置调用以调用该事件。
回答by Olioul Islam Rahi
You can try this way, It works for me:
你可以试试这种方式,它对我有用:
public delegate void MyEventHaldler(object sender, EventArgs e);
public class B
{
public virtual event MyEventHaldler MyEvent;
protected override void OnChanged(EventArgs e)
{
if (MyEvent != null)
MyEvent(this, e);
}
}
public class D : B
{
public override event MyEventHaldler MyEvent;
protected override void OnChanged(EventArgs e)
{
if (MyEvent != null)
MyEvent(this, e);
}
}
回答by Zeraphil
not to resurrect an old thread but in case anybody is looking, what I did was
不要复活旧线程,但万一有人在看,我所做的是
protected EventHandler myPropertyChangedDelegate;
public event EventHandler MyPropertyChanged
{
add { myPropertyChangedDelegate += value; }
remove { myPropertyChangedDelegate -= value; }
}
This lets you inherit the event in a derived class so you can invoke it without requiring to wrap the method while keeping the += syntax. I guess you could still do that with the wrapping methods if you did
这使您可以在派生类中继承事件,因此您可以在保持 += 语法的同时调用它而无需包装方法。如果你这样做了,我想你仍然可以用包装方法来做到这一点
public event EventHandler MyPropertyChanged
{
add { AddDelegate(value); }
remove { RemoveDelegate(value); }
}