当前位置:  开发笔记 > 编程语言 > 正文

从C++/CLI引发事件的正确方法?

如何解决《从C++/CLI引发事件的正确方法?》经验,为你挑选了3个好方法。

我想知道从C++/CLI引发事件的正确方法是什么.在C#中,我应首先制作处理程序的副本,检查它是否为空,然后调用它.C++/CLI有类似的做法吗?



1> IV...:

这不是全部故事!您通常不必担心C++/CLI中的空事件处理程序.这些检查的代码是为您生成的.考虑以下简单的C++/CLI类.

public ref class MyClass
{
public:
    event System::EventHandler ^ MyEvent;
};

如果您编译此类,并使用Reflector对其进行反汇编,则会获得以下c#代码.

public class MyClass
{
    // Fields
    private EventHandler MyEvent;

    // Events
    public event EventHandler MyEvent
    {
        [MethodImpl(MethodImplOptions.Synchronized)] add
        {
            this.MyEvent = (EventHandler) Delegate.Combine(this.MyEvent, value);
        }
        [MethodImpl(MethodImplOptions.Synchronized)] remove
        {
            this.MyEvent = (EventHandler) Delegate.Remove(this.MyEvent, value);
        }
        raise
        {
            EventHandler  = null;
             = this.MyEvent;
            if ( != null)
            {
                (value0, value1);
            }
        }
    }
}

通常的检查是在raise方法中完成的.除非你真的想要自定义行为,否则你应该觉得在上面的类中声明你的事件并且不必担心空处理程序就可以提高它.



2> Konrad Rudol..:

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();
}



3> Reilly..:

如果你的问题是加注不是私有的,那么明确地实现它就像文档说:

http://msdn.microsoft.com/en-us/library/5f3csfsa.aspx

综上所述:

如果您只使用event关键字,则会创建一个"普通"事件.编译器为您生成add/remove/raise和委托成员.生成的raise函数(如文档所述)检查nullptr.这里记录了一些微不足道的事件:

http://msdn.microsoft.com/en-us/library/4b612y2s.aspx

如果您想要"更多控制",例如将raise设置为 private,则必须显式实现链接中显示的成员.您必须为委托类型显式声明数据成员.然后使用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.

推荐阅读
惬听风吟jyy_802
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有