variable programming practices microsoft guidelines convenciones coding codigo code classes best and c# coding-style

programming - convenciones de codigo c#



Reemplazo del código de la placa de la caldera: ¿hay algo malo sobre este código? (3)

Recientemente he creado estos dos métodos (no relacionados) para reemplazar gran cantidad de código de placa de caldera en mi aplicación de formas de inversión. Por lo que puedo decir, funcionan bien, pero necesito algún consuelo / consejo sobre si hay algunos problemas que me pueden estar perdiendo.

(de memoria)

static class SafeInvoker { //Utility to avoid boiler-plate InvokeRequired code //Usage: SafeInvoker.Invoke(myCtrl, () => myCtrl.Enabled = false); public static void Invoke(Control ctrl, Action cmd) { if (ctrl.InvokeRequired) ctrl.BeginInvoke(new MethodInvoker(cmd)); else cmd(); } //Replaces OnMyEventRaised boiler-plate code //Usage: SafeInvoker.RaiseEvent(this, MyEventRaised) public static void RaiseEvent(object sender, EventHandler evnt) { var handler = evnt; if (handler != null) handler(sender, EventArgs.Empty); } }

EDITAR: vea la pregunta relacionada aquí

ACTUALIZAR

Después de los problemas de interbloqueo (relacionados en esta pregunta ), he cambiado de Invocar a BeginInvoke (ver una explicación aquí ).

Otra actualización

Con respecto al segundo fragmento, cada vez me siento más inclinado a utilizar el patrón ''delegado vacío'', que corrige este problema ''en origen'' al declarar el evento directamente con un controlador vacío, así:

event EventHandler MyEventRaised = delegate {};


Esto es bueno. Haga que sean métodos de extensión para limpiar su código un poco más. Por ejemplo:

//Replaces OnMyEventRaised boiler-plate code //Usage: SafeInvoker.RaiseEvent(this, MyEventRaised) public static void Raise(this EventHandler eventToRaise, object sender) { EventHandler eventHandler = eventToRaise; if (eventHandler != null) eventHandler(sender, EventArgs.Empty); }

Ahora en tus eventos puedes llamar a: myEvent.Raise (this);


Patrones similares han funcionado para mí sin problemas. Sin embargo, no estoy seguro de por qué está envolviendo la acción en MethodInvoker.


Debido al hecho de que Benjol no sabe, por qué coloca Action en un MethodInvoker y broccliman destinado a usarlo como una función de extensión, aquí está el código de limpieza:

static class SafeInvoker { //Utility to avoid boiler-plate InvokeRequired code //Usage: myCtrl.SafeInvoke(() => myCtrl.Enabled = false); public static void SafeInvoke(this Control ctrl, Action cmd) { if (ctrl.InvokeRequired) ctrl.BeginInvoke(cmd); else cmd(); } //Replaces OnMyEventRaised boiler-plate code //Usage: this.RaiseEvent(myEventRaised); public static void RaiseEvent(this object sender, EventHandler evnt) { var temp = evnt; if (temp != null) temp(sender, EventArgs.Empty); } }

Solo una última nota: MethodInvoker y Action son solo delegados que tienen exactamente la misma estructura. Debido a este caso, ambos son reemplazables entre sí. La raíz de este choque de nombres proviene del legado. Al principio (.Net 2.0) solo MethodInvoker y Action(T) . Pero debido al hecho de que todos los que usaron Action(T) desean tener una Action y consideraron que no es natural tomar MethodInvoker . Entonces, en .Net 3.5, Action , Action(T1, T2, T3, T4) y todos los delegados de Func agregaron también, pero MethodInvoker ya no se pudo eliminar sin realizar cambios importantes.

Adicional:

Si puede usar .Net 3.5, el código anterior está bien, pero si está vinculado a .Net 2.0, puede usarlo como una función normal como antes y reemplazar la Action de MethodInvoker .