Events C++;托管事件的Cli实现
我想在cli/c++组件中实现一个托管接口。假设我的界面有这样一个事件:Events C++;托管事件的Cli实现,events,c++-cli,Events,C++ Cli,我想在cli/c++组件中实现一个托管接口。假设我的界面有这样一个事件: public interface IManagedInterface { event EventHandler<ServiceCollectionChangedEventArgs> ServiceCollectionChanged; } 公共接口IManagedInterface { 事件处理程序ServiceCollectionChanged; } 存在头文件和.cpp文件的My cli组件。在我的
public interface IManagedInterface
{
event EventHandler<ServiceCollectionChangedEventArgs> ServiceCollectionChanged;
}
公共接口IManagedInterface
{
事件处理程序ServiceCollectionChanged;
}
存在头文件和.cpp文件的My cli组件。在我的标题中,我定义了事件和一个私有方法来引发它
ref class NativeImplementation : public IManagedInterface
{
public:
virtual event System::EventHandler<ServiceCollectionChangedEventArgs^>^ ServiceCollectionChanged;
private:
void RaiseServiceCollectionChanged(System::Type^ type, ChangeAction action);
};
ref类本地实现:公共IManagedInterface
{
公众:
虚拟事件系统::EventHandler^ServiceCollectionChanged;
私人:
作废RaiseServiceCollectionChanged(系统::类型^Type,ChangeAction);
};
在我的.cpp文件中,我想实现raise方法,而这正是我努力的方向
void NativeImplementation::RaiseServiceCollectionChanged(Type^ type, ChangeAction action)
{
EventHandler<ServiceCollectionChangedEventArgs^>^ local = NativeImplementation::ServiceCollectionChanged;
if (local != nullptr) {
local(this, gcnew ServiceCollectionChangedEventArgs(type, action));
}
}
}
void NativeImplementation::RaiseServiceCollectionChanged(类型^Type,ChangeAction)
{
EventHandler^local=NativeImplementation::ServiceCollectionChanged;
如果(本地!=nullptr){
本地(这是gcnew ServiceCollectionChangedEventArgs(类型、操作));
}
}
}
我习惯于在引发事件之前进行上述检查,但编译器抱怨“错误无效使用事件成员”。有人能帮我吗?在C++中,我甚至需要这些检查吗?
感谢在C#中,引发事件的习惯用法是将事件复制到局部变量,检查是否为null,然后使用局部变量调用处理程序,而不是重新读取事件对象
// C# Idiom
void RaiseEvent()
{
EventHandler<Whatever> handler = this.MyEvent;
if (handler != null)
handler(this, new Whatever());
}
在引擎盖下,C#为每个事件成员定义了两个方法:
add
和remove
,在使用+=
和-=
时调用。上面的习惯用法是必要的,因为没有内置的null检查,并且如果在null检查和实际触发事件之间的另一个线程上修改事件,则需要本地副本。C++/CLI定义了三种方法:add
、remove
和raise
,而raise
方法实现了空检查和本地复制,这与C#一样,要求每个开发人员自己实现 您的事件是实例成员而不是静态成员,因此您应该在raise方法中使用此关键字来限定事件名称的范围(或者根本不限定它的范围)
EventHandler^local=this->ServiceCollectionChanged;
// C++/CLI *only*. This will cause bugs if you do this in C#.
void NativeImplementation::RaiseServiceCollectionChanged(Type^ type, ChangeAction action)
{
this->ServiceCollectionChanged(this, gcnew ServiceCollectionChangedEventArgs(type, action));
}
EventHandler<ServiceCollectionChangedEventArgs^>^ local = this->ServiceCollectionChanged;