Me preguntaba cuál es la forma correcta de generar eventos desde C++/CLI. En C# one s hould first make a copy of the handler, check if it's not null, and then call it. ¿Existe una práctica similar para C++/CLI?¿La forma correcta de generar eventos desde C++/CLI?
Respuesta
C++/CLI le permite anular raise
en controladores custom event, por lo que no tiene que comprobar null
o copiar cuando se produce un evento. Por supuesto, dentro de su medida personalizada raise
usted todavía tiene que hacer esto.
ejemplo, una adaptación de la MSDN para la 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();
}
Esto 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 desmontar usando Reflector, se obtiene 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 comprobaciones habituales se realizan en el método de elevación. 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 el problema es que aumento no es privado, a continuación, poner en práctica de forma explícita al igual que los documentos dicen:
http://msdn.microsoft.com/en-us/library/5f3csfsa.aspx
En resumen:
Si usted sólo tiene que utilizar el evento palabra clave, crea un evento "trivial". El compilador genera añadir/eliminar/aumento y el miembro delegado para usted. El aumento generada función (como dicen los documentos) comprueba si el nullptr. eventos triviales están documentados aquí:
http://msdn.microsoft.com/en-us/library/4b612y2s.aspx
Si desea "más control", por ejemplo para hacer aumento privado, entonces usted tiene que poner en práctica de manera explícita los miembros como se muestra en el enlace. Debe declarar explícitamente un miembro de datos para el tipo de delegado. A continuación, se utiliza el evento palabra clave 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
prolija, pero no lo es.
-reilly.
- 1. ¿Cuál es la forma correcta de manejar eventos en C++?
- 2. Forma correcta de generar números de orden en SQL Server
- 3. Qt: ¿Forma correcta de publicar eventos en un QThread?
- 4. ¿es esta una forma correcta de generar claves rsa?
- 5. VS Mensaje Generar eventos
- 6. Forma correcta de poner comentarios en la línea de comando de eventos de compilación?
- 7. ¿La forma correcta de deshacerse de Quartz.NET?
- 8. ¿Cuál es la forma correcta de generar atributos/texto HTML con comillas en Razor/MVC3?
- 9. ¿La forma correcta de finalizar un BeginInvoke?
- 10. ¿Cuál es la forma correcta de redirigir?
- 11. iphone NSManagedObject - ¿La forma correcta de desasignar?
- 12. Forma correcta de generar un bloque grande de HTML en PHP
- 13. Forma correcta de deshacerse de un BackGroundWorker
- 14. ¿Bootstrap forma el diseño de la forma "correcta"?
- 15. forma correcta de utilizar StringBuilder
- 16. Forma correcta de detener IntentService
- 17. generar eventos en una clase estática
- 18. C#: Forma correcta de cerrar SerialPort con Winforms
- 19. cuál es la forma correcta de leer desde un datarow si la celda puede ser nula
- 20. Android: forma correcta de saltar entre fragmentos
- 21. Forma correcta de probar gemas
- 22. Forma correcta de crear formularios
- 23. La forma correcta para implementar ThreadPool.RegisterWaitForSingleObject
- 24. Forma correcta de sincronizar ArrayList en java
- 25. Generar ERD desde SQLyog
- 26. Generar eventos de teclado para la aplicación más avanzada
- 27. Forma correcta de documentar o diagramar modelos de eventos personalizados en DOM
- 28. La forma correcta de enviar correos electrónicos desde el servicio de Windows
- 29. ¿Cuál es la forma correcta de usar bitfields en C?
- 30. La forma correcta de dibujar texto en OpenGL ES 2
Mi problema con este enfoque es que el método "subir" no es privado (como en C#) y se muestra en el intellisense. –
@Filip: Así que ve con un evento personalizado y pon 'privado:' al frente. –