C# -事件-只能出现在+;=或-=
我有一个循环中的事件。我试图防止同一方法被多次添加到事件中。我已经实现了C# -事件-只能出现在+;=或-=,c#,event-handling,C#,Event Handling,我有一个循环中的事件。我试图防止同一方法被多次添加到事件中。我已经实现了add和remove访问器 但是,我得到一个错误,指出: ItemsProcessed只能出现在+=或-=的左侧 当我试着给他们打电话时,即使是在同一个班级里 ItemsProcessed(this, new EventArgs()); // Produces error public event EventHandler ItemsProcessed { add { ItemsProces
add
和remove
访问器
但是,我得到一个错误,指出:
ItemsProcessed只能出现在+=或-=的左侧
当我试着给他们打电话时,即使是在同一个班级里
ItemsProcessed(this, new EventArgs()); // Produces error
public event EventHandler ItemsProcessed
{
add
{
ItemsProcessed -= value;
ItemsProcessed += value;
}
remove
{
ItemsProcessed -= value;
}
}
对于显式事件,您需要提供自己的后备存储—委托字段或类似于EventHandlerList
的内容。当前代码是递归的。尝试:
private EventHandler itemsProcessed;
public event EventHandler ItemsProcessed
{
add
{
itemsProcessed-= value;
itemsProcessed+= value;
}
remove
{
itemsProcessed-= value;
}
}
然后(请注意,我对“即将变成null
”边缘案例重新线程化有点谨慎):
使用更新的C#版本,这可以简化:
itemsProcessed?.Invoke(this, EventArgs.Empty);
什么错误?我猜是它的堆栈溢出错误,因为您正在对自己的serlf(相同事件)调用add和remove。此外,您不能引发事件访问器
有效的方法是创建备份私有事件,该事件将被添加到或从公共访问器中删除,您应该引发此私有事件
Dang,晚了一分钟。如果显式实现了EventHandler
,则在触发事件时无法引用“属性”。您必须参考备份存储。我无法从您的帖子中判断您是否试图从派生类引发事件,但我发现一件事是,您无法在基类中定义事件,然后(直接)在派生类中引发它,原因我还不清楚
因此,我在基类中定义了受保护的函数来引发事件(在这些基类中定义),如下所示:
// The signature for a handler of the ProgressStarted event.
// title: The title/label for a progress dialog/bar.
// total: The max progress value.
public delegate void ProgressStartedType(string title, int total);
// Raised when progress on a potentially long running process is started.
public event ProgressStartedType ProgressStarted;
// Used from derived classes to raise ProgressStarted.
protected void RaiseProgressStarted(string title, int total) {
if (ProgressStarted != null) ProgressStarted(title, total);
}
然后在派生类中,我调用RaiseProgressStarted(title,total),而不是调用ProgressStarted(title,total)
这似乎是一个很长的路要走。也许其他人知道解决此问题的更好方法。此外,您似乎通过访问ItemsProcessed
函数本身中的ItemsProcessed
创建了一个无限循环。作为参考,EventName(args)
调用技巧仅适用于类似字段的事件,其中某些操作隐式解析为类中的字段(而不是事件)。我不得不说“一些”,因为确切的列表在C#3和C#4之间变化。不,他不知道堆栈溢出,因为他的代码甚至没有编译。是的,当Marc的答案发布后,我就不再考虑它了。。你是对的。一个缺点是:只能在类内访问为什么要访问类外的私有支持事件?子类化,duh。使内容受到保护。@nyrguds子类化很少有很好的理由访问支持字段;对于事件,更常见的方法是protectedvirtual void OnItemsProcessed()=>itemsProcessed?.Invoke(这是EventArgs.Empty)代码>-工作完成,无需公开对fieldWell的访问,我正在尝试创建一个自定义OnMouseWheel
,它可以选择执行原始链接的控件。MouseWheel
事件。。。我不能不禁用滚动。真令人沮丧。鼠标滚动是一种奇怪的半自动的东西。我刚刚意识到这是一篇5年前的文章。我遇到了这个问题,并弄明白了我到底在做什么,所以我发布了这个答案。也许这对某人会有帮助。呵呵,我刚刚又遇到了这个问题,不太记得是什么原因造成的,以及我是如何解决的,我从11个月前就找到了自己的答案。这很有趣。2019年,这解决了我的问题,感谢2015年关于2010年问题的帖子!:-我想这一定是事实,它解决了问题,但我真正想知道的是原因。也许在过去的几年里,有人已经明白了这一点?
// The signature for a handler of the ProgressStarted event.
// title: The title/label for a progress dialog/bar.
// total: The max progress value.
public delegate void ProgressStartedType(string title, int total);
// Raised when progress on a potentially long running process is started.
public event ProgressStartedType ProgressStarted;
// Used from derived classes to raise ProgressStarted.
protected void RaiseProgressStarted(string title, int total) {
if (ProgressStarted != null) ProgressStarted(title, total);
}