在C#中,我可以检查一个事件是否有任何监听器:
C#示例:
public static event EventHandler OnClick;
if (OnClick != null)
OnClick(null, new EventArgs() );
在C ++ / CLI中检查事件是否为null是不必要的。
C ++ / CLI示例:
delegate void ClickDelegate( Object^ sender, MyEventArgs^ e );
event ClickDelegate^ OnClick;
OnClick (sender, args);
但是,在我正在进行的项目中,如果没有侦听器,我不想构造MyEventArgs对象。
如何确定OnClick是否在C ++中有任何侦听器?
答案 0 :(得分:2)
您似乎无法像使用“平凡事件”一样检查它,因为您无法直接访问基础字段(与C#中的自动实现属性一样)。
如果要执行此操作,可以显式指定事件的访问者方法和支持字段。有关如何做到这一点,请参阅How to: Define Event Accessor Methods。
答案 1 :(得分:2)
基于@BenVoigt对@ svick的原始答案和新MSDN article on C++/CLI events的评论讨论,我创建了一个如何正确执行此操作的最小示例。此代码在面向.NET 4.5的Visual Studio 2013 CLR项目模板中编译和运行。我没有测试其他运行时和目标,但它只使用基本的.NET组件。
System::Threading::Monitor
使用标准事件处理程序约定:
void MyEventHandler(Object ^sender, MyEventArgs ^e);
使用+=
和-=
除非支持字段为nullptr
// compile with: /clr
#include "stdafx.h"
using namespace System;
using System::Threading::Monitor;
public delegate void MyDelegate(Object ^sender, EventArgs ^e);
ref class EventSource {
private:
MyDelegate ^myEvent;
Object ^eventLock;
public:
EventSource()
{
eventLock = gcnew Object();
}
event MyDelegate^ Event {
void add(MyDelegate^ handler) {
Monitor::Enter(eventLock);
if (myEvent == nullptr)
{
myEvent = static_cast<MyDelegate^> (
Delegate::Combine(myEvent, handler));
}
else
{
myEvent += handler;
}
Monitor::Exit(eventLock);
}
void remove(MyDelegate^ handler) {
Monitor::Enter(eventLock);
if (myEvent != nullptr)
{
myEvent -= handler;
}
Monitor::Exit(eventLock);
}
void raise(Object ^sender, EventArgs ^e) {
Monitor::Enter(eventLock);
if (myEvent != nullptr)
myEvent->Invoke(sender, e);
Monitor::Exit(eventLock);
}
}
void Raise()
{
Event(this, EventArgs::Empty);
}
};
public ref struct EventReceiver {
void Handler(Object ^sender, EventArgs ^e) {
Console::WriteLine("In event handler");
}
};
int main() {
EventSource ^source = gcnew EventSource;
EventReceiver ^receiver = gcnew EventReceiver;
// hook event handler
source->Event += gcnew MyDelegate(receiver, &EventReceiver::Handler);
// raise event
source->Raise();
// unhook event handler
source->Event -= gcnew MyDelegate(receiver, &EventReceiver::Handler);
// raise event, but no handlers
source->Raise();
}