Events 从C++/CLI?

Events 从C++/CLI?,events,c++-cli,raise,Events,C++ Cli,Raise,我想知道从C++/CLI引发事件的正确方法是什么。在C#one s中。C++/CLI有类似的做法吗?C++/CLI允许您在处理程序中重写raise,这样您就不必在引发事件时测试null或复制。当然,在自定义的raise中,您仍然需要这样做 示例,根据MSDN改编以确保正确性: public delegate void f(int); public ref struct E { f ^ _E; public: void handler(int i) { System::C

我想知道从C++/CLI引发事件的正确方法是什么。在C#one s中。C++/CLI有类似的做法吗?

C++/CLI允许您在处理程序中重写
raise
,这样您就不必在引发事件时测试
null
或复制。当然,在自定义的
raise
中,您仍然需要这样做

示例,根据MSDN改编以确保正确性:

public delegate void f(int);

public ref struct E {
   f ^ _E;
public:
   void handler(int i) {
      System::Console::WriteLine(i);
   }

   E() {
      _E = nullptr;
   }

   event f^ Event {
      void add(f ^ d) {
         _E += d;
      }
      void remove(f ^ d) {
        _E -= d;
      }
      void raise(int i) {
         f^ tmp = _E;
         if (tmp) {
            tmp->Invoke(i);
         }
      }
   }

   static void Go() {
      E^ pE = gcnew E;
      pE->Event += gcnew f(pE, &E::handler);
      pE->Event(17);
   }
};

int main() {
   E::Go();
}

这不是全部!在C++/CLI中,通常不必担心空事件处理程序。这些检查的代码是为您生成的。考虑下面的C++ C++CLI类。< /P>
public ref class MyClass
{
public:
    event System::EventHandler ^ MyEvent;
};
如果编译这个类,并使用反汇编,则会得到以下c#代码

公共类MyClass
{
//田地
私有事件处理程序MyEvent;
//事件
公共事件处理程序MyEvent
{
[MethodImpl(MethodImplOptions.Synchronized)]添加
{
this.MyEvent=(EventHandler)Delegate.Combine(this.MyEvent,value);
}
[MethodImpl(MethodImplOptions.Synchronized)]删除
{
this.MyEvent=(EventHandler)Delegate.Remove(this.MyEvent,value);
}
提升
{
EventHandler=null;
=this.MyEvent;
如果(!=null)
{
(价值0,价值1);
}
}
}
}

通常的检查是在raise方法中进行的。除非您真的想要自定义行为,否则您应该在上面的类中声明您的事件,并在不担心空处理程序的情况下引发它。

如果您的问题是,引发不是私有的,那么请显式实现它,如文档所述:

总之:

如果只使用事件关键字,则会创建一个“普通”事件。编译器为您生成添加/删除/提升和代理成员。生成的raise函数(如文档所述)检查nullptr。这里记录了一些琐碎的事件:

如果您想要“更多控制”,例如使raise私有化,则必须显式实现链接中所示的成员。必须显式声明委托类型的数据成员。然后使用event关键字声明与事件相关的成员,如Microsoft示例中所示:

// event keyword introduces the scope wherein I'm defining the required methods
// "f" is my delegate type
// "Event" is the unrealistic name of the event itself
event f^ Event
{
      // add is public (because the event block is public)
      // "_E" is the private delegate data member of type "f"
      void add(f ^ d) { _E += d; }

   // making remove private
   private:
      void remove(f ^ d) { _E -= d; }

   // making raise protected
   protected:
      void raise(int i)
      { 
         // check for nullptr
         if (_E)
         {
            _E->Invoke(i);
         }
      }
}// end event block
罗嗦,但就是这样


-reilly.

我的问题是,这种方法的“raise”方法不是私有的(如C#),而是以智能感知方式显示的。@Filip:因此,请使用自定义事件,并将
私有:
放在前面。
// event keyword introduces the scope wherein I'm defining the required methods
// "f" is my delegate type
// "Event" is the unrealistic name of the event itself
event f^ Event
{
      // add is public (because the event block is public)
      // "_E" is the private delegate data member of type "f"
      void add(f ^ d) { _E += d; }

   // making remove private
   private:
      void remove(f ^ d) { _E -= d; }

   // making raise protected
   protected:
      void raise(int i)
      { 
         // check for nullptr
         if (_E)
         {
            _E->Invoke(i);
         }
      }
}// end event block