Надлежащий способ сгенерировать события от C++ / CLI?

15
задан Community 23 May 2017 в 11:54
поделиться

2 ответа

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();
}
19
ответ дан 1 December 2019 в 00:10
поделиться

Это еще не вся история! Обычно не стоит беспокоиться об обработчиках нулевых событий в C++/CLI. Код для этих проверок сгенерирован для вас. Рассмотрим следующий тривиальный класс C++/CLI.

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

Если скомпилировать этот класс и разобрать его с помощью Рефлектора, то получим следующий код на языке c#.

public class MyClass
{
    // Fields
    private EventHandler <backing_store>MyEvent;

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

Обычные проверки выполняются в методе raise. Если только вы действительно не хотите пользовательского поведения, то вы должны чувствовать себя комфортно, объявляя свое событие как в вышеуказанном классе, и поднимая его, не опасаясь нулевого обработчика.

29
ответ дан 1 December 2019 в 00:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: