studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones events c++-cli raise

events - programacion - ¿La forma correcta de generar eventos desde C++/CLI?



manual de programacion android pdf (3)

Me preguntaba cuál es la forma correcta de generar eventos desde C ++ / CLI. En C # uno primero debe hacer una copia del controlador, verificar si no es nulo, y luego llamarlo . ¿Existe una práctica similar para C ++ / CLI?


C ++ / CLI le permite anular el raise en los controladores de eventos personalizados para que no tenga que probar null o copiar cuando se genera el evento. Por supuesto, dentro de tu raise personalizado, tienes que hacer esto.

Ejemplo, adaptado de MSDN para corrección:

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


¡Esta no es toda la historia! Por lo general, no tiene que preocuparse por los controladores de eventos nulos en C ++ / CLI. El código para estas verificaciones se genera para usted. Considere la siguiente clase trivial de C ++ / CLI.

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

Si compila esta clase y la desensambla con Reflector , obtendrá el siguiente código 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); } } } }

Las verificaciones usuales se realizan en el método de aumento. A menos que realmente desee un comportamiento personalizado, debe sentirse cómodo declarando su evento como en la clase anterior y criándolo sin temor a un controlador nulo.


Si su problema es que subir no es privado, impleméntelo explícitamente como dicen los documentos:

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

En resumen:

Si solo usa la palabra clave del evento , crea un evento "trivial". El compilador genera add / remove / raise y el miembro delegado por usted. La función de aumento generado (como dicen los documentos) busca nullptr . Los eventos triviales están documentados aquí:

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

Si desea "más control", por ejemplo, para hacer que aumente la privacidad, debe implementar explícitamente los miembros como se muestra en el enlace. Debe declarar explícitamente un miembro de datos para el tipo de delegado. Luego usa la palabra clave event para declarar los miembros relacionados con el evento, como en el ejemplo de 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

Wordy, pero ahí está.

-reilly