Pregunta

¿Cómo estás formateando sus bloques try..catch.finally? Sobre todo cuando sólo se envolviéndolo alrededor de una pequeña cantidad de código, sopla todo y hace que el código ilegible bastante antiestético y en mi opinión.

Tales como:

try
{
     MyService service = new Service();
     service.DoSomething();
     return something;
}
catch (Exception ex)
{
     LogSomething();
     return somethingElse;
}
finally
{
     MarkAsComplete();
     service.Dispose();
}

Estos 7 líneas de código se convirtieron en un lío de 16 líneas.

¿Alguna sugerencia sobre el formateo mejor try..catch..finally?

¿Fue útil?

Solución

En realidad, esto se lee muy bien a mí. Si su código real se parece mucho a esto, entonces yo realmente no preocuparse por ello. Está muy claro lo que está sucediendo.

Si su código real es más complejo, y luego considerar romper los bloques en métodos bien llamada.

Otros consejos

puede utilizar un bloque using en lugar de un Dispose() explícita, o de lo contrario la probabilidad que tenga que comprobar NULL antes de desecharlo, bloques using lo hace por ti. lamentablemente lo hace aumento de anidación = /

try
{
     using(MyService service = new MyService()) 
     {
        service.DoSomething();
        return something;
     }
}
catch (SpecificException ex)
{
     LogSomething(ex);
     return somethingElse;
}
finally
{
     MarkAsComplete();
}

Bueno, creo que eso está bien. Algo de esto consigue que intot rizado debate colocación de ortesis. Usted puede hacer esto:

try {
  //
} catch(Exception ex) {
  //
} finally {
  //
}

Yo prefiero lo que tiene sin embargo. Sin embargo, es posible que desee considerar la revisión de su código para tener sólo una instrucción de retorno. Me parece que es un poco mejor diseño.

formateo del código con los soportes en la misma línea:

try {
   MyService service = new Service();
   service.DoSomething();
   return something;
} catch (Exception ex) {
   LogSomething();
   return somethingElse;
} finally {
   MarkAsComplete();
   service.Dispose();
}

Yo prefiero añadir líneas en blanco si quiero más espaciado. Que también funciona como separador entre los bloques lógicos de código.

Se podría pensar acerca de los contenedores (fábricas muy inteligentes) y asesoramiento (para manejar todos los detalles sucios).

Dear Mr. Container Sir,
Whenever I request from you an instance object of the interface ISomething,
    please construct for me an instance of the concrete class SomethingImpl;
    in addition, please see to it (however you do it) that, whenever I call a
    method on this instance, it is wrapped within a complicated and messy try-
    catch-finally which logs exceptions and mark calls as completed. That way,
    all I have to do is write the business logic that goes into the SomethingImpl
    and I don't have to worry about all the messy infrastuctural details.
Sincerely,
Mr. Agile.

Es posible que vea esto, en clave, como:

//a class that knows how to take care of the messy infrastructure details
public class MyMessyInterceptor : IInterceptor {
    public void Intercept(IInvocation invocation) {
        //handle the messy details of continuing with the method-invocation,
        //but within a try-catch-finally that includes exception handling and
        //call logging.
    }
}

//a function that will configure a container (very smart factory)
public IContainer CreateContainer() {
    var builder = new ContainerBuilder();

    //tell the container-builder about the interceptor
    builder
        .Register(c => new MyMessyInterceptor())
        .Named("keep-my-code-clean")
    ;

    //tell the container what to do when you ask it for a ISomething
    builder
        .Register<SomethingImpl>()
        .As<ISomething>()
        .InterceptedBy("keep-my-code-clean")
    ;

    return builder.BuildContainer();
}

//some function out there in your code somewhere that needs to make a
//service call; there's hundreds of functions out there just like this
//in your code, and they all just got much simpler
public object GottaGoDoSomething() {
    //find the container
    var container = GetTheSingletonContainerObject();
    //ask for an instance of ISomething - it knows to provide a
    //SomethingImpl wrapped in an interceptor that takes care of all
    //the logging and exception handling
    var something = container.resolve<ISomething>();
    //call the big method
    return something.DoSomething();
    //magically (not really), the exception handling and logging are
    //already taken care of
}

El subir con la clase de interceptor ocurre sólo una vez. El registro de cada interceptor y la clase de servicio también pasa sólo una vez. Configuración del contenedor (fábrica muy inteligente) es ciertamente complicado.

Sin embargo, cada lugar en su código que tiene que utilizar el objeto de servicio, y tiene que encajar que su uso dentro de la infraestructura detalles complicados y desordenados, tales como el manejo de excepciones y la explotación forestal, acaba de conseguir muy limpia y muy complicada. Sólo hay una CreateContainer, pero hay cientos de GottaGoDoSomethings, así que eso es un montón de fácil a costa de un poco complicado.

(Notas: El ejemplo de código utiliza el marco contenedor Autofac y el marco interceptor Castillo Soy consciente de que este es un ejemplo del patrón de servicio en la ubicación, no el patrón de dependencia de la inyección, pero el punto era ilustrar interceptores y. registrarse con un recipiente, no para ilustrar la dependencia de la inyección.)

Los espacios en blanco. Como requisitos mínimos siempre pongo una línea de espacio en blanco antes de cada instrucción de retorno y en medio de "hacer cosas" y "creación de variables" secciones de código.

try
{
     MyService service = new Service();

     service.DoSomething();

     return something;

 }
catch (Exception ex)
{
     LogSomething();

     return somethingElse;

}
finally
{
     MarkAsComplete();
     service.Dispose();
}

mucho mejor.

Creo que su formato se lee bien también. Mi sugerencia sería utilizar sólo la declaración catch moderación. Sólo se debe usar cuando realmente se necesita coger algo. De lo contrario puede dejar que otras partes del programa manejar la excepción. El conjunto "fallar temprano" concepto.

try
{
    //do something that may throw an exception.
}
finally
{
    //handle clean up.
}

//let a method further down the stack handle the exception.

Personalmente, tiendo a seguir el estilo anterior en mi código ... Se da espacio para hacer comentarios, y muestra el flujo de mi lógica mejor.

Tengo una pantalla panorámica que enciendo su lado, por lo que el espacio en blanco permite que las distintas columnas se alineen bien y no me ha hecho mucho daño porque tengo tanta pantalla de bienes raíces, ya que es ...

try { // getting a service

     MyService service = new Service();
     service.DoSomething();

     return something;

}

catch (Exception ex) { // the fact that a service might be full/timedout

     LogSomething();

     return somethingElse;

} 

finally { // remove any resources the service may still hold.

     MarkAsComplete();
     service.Dispose();

}

Yo también, como lo que originalmente tenía. líneas físicas en un archivo .cs no le cuesta nada, y no cambian su código de salida final. A fin de utilizar todo lo que necesita con el fin de proporcionar la mejor legibilidad para usted o su equipo.

De hecho, en realidad se debe tratar de usar más líneas que el 16 se muestra aquí cuando código, mediante la adición de comentarios para sí mismo u otros.

Al añadir

// a comment that says what's going on

Con frecuencia, se puede recordar mejor a ti mismo lo que se supone que esto Try.Catch a hacer cuando vuelva a ella después de 6 meses.

Siempre trato de refactorizar todos mis bloques catch try y encapsular en su propio método.

Esto siempre parece hacer que todo sea más fácil de leer, además de que es una buena práctica de programación para hacer que sus métodos de hacer solamente una cosa. Lo más probable es que si usted tiene código de arriba y por debajo de su try-catch-finally, entonces usted está haciendo más de una cosa.

Si realmente quiere deshacerse de la obligatorio y formato fea (sí estoy de acuerdo: p)

vaya a Programación Orientada a Aspectos , y obtendrá el try ... catch ... finally incrustado de forma gratuita en su montaje y excepción registrada automáticamente.

Trate PostSharp o Spring.Net

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top