2009-10-05 10 views
9

¿Hay alguna manera de decorar un método que haga algo de registro, y luego lanzar una excepción incondicionalmente, como tal?¿Cómo marcar un método se lanzará incondicionalmente?

tengo código como este:

void foo(out int x) 
{ 
    if(condition()) { x = bar(); return; } 

    // notice that x is not yet set here, but compiler doesn't complain 

    throw new Exception("missed something."); 
} 

si trato de escribirlo como esto consigo un problema:

void foo(out int x) 
{ 
    if(condition()) { x = bar(); return; } 

    // compiler complains about x not being set yet 

    MyMethodThatAlwaysThrowsAnException("missed something."); 
} 

¿Alguna sugerencia? Gracias.

+0

¿Qué problema obtienes? –

+0

"x tiene un atributo de salida y no se ha establecido aún al final del método" – k0dek0mmand0

+1

Estoy confundido: ¿cómo se lanza incondicionalmente si no se lanza cuando se establece x (y se realiza una devolución) – Matt

Respuesta

17

¿Qué le parece esto?

bool condition() { return false; } 
int bar() { return 999; } 
void foo(out int x) 
{ 
    if (condition()) { x = bar(); return; } 
    // compiler complains about x not being set yet 
    throw MyMethodThatAlwaysThrowsAnException("missed something."); 
} 
Exception MyMethodThatAlwaysThrowsAnException(string message) 
{ 
    //this could also be a throw if you really want 
    // but if you throw here the stack trace will point here 
    return new Exception(message); 
} 
2

Si sabe que la excepción siempre será arrojada, ¿por qué es importante? Sólo hay que establecer la variable a algo por lo que puede compilar:

void foo(out int x) 
{ 
    if(condition()) { x = bar(); return; } 

    x = 0; 

    MyMethodThatAlwaysThrowsAnException("missed something."); 
} 
+3

Eso es exactamente lo que quería evitar.:) – k0dek0mmand0

0

No responde a su pregunta, pero al utilizar parámetros cabo siempre es una buena idea para inicializar ellos en el principio del método. De esta manera usted no tiene ningún errores de compilación:

void foo(out int x) 
{ 
    x = 0; 
    if(condition()) { x = bar(); return; } 
    MyMethodThatAlwaysThrowsAnException("missed something."); 
} 
+4

Creo que los parámetros deben asignarse donde tiene sentido o porque pueden evitar algunos errores ocultos en tiempo de compilación solo porque se olvidó de asignar el parámetro en alguna ruta de código. –

1

x es un cabo parámetros y se debe establecer antes de seguir adelante

+3

menos que se produce una excepción – k0dek0mmand0

+1

Todavía es una buena política para asegurar que ningún cabo parámetros se establecen desde el principio en el método y asignar valores por defecto a ellos si no. –

2

No hay manera de marcar un método de esta manera.

Posiblemente irrelevante, pero el patrón en su ejemplo, usando un parámetro out, es un poco extraño. ¿Por qué no simplemente tener un tipo de devolución en el método?

int Foo() 
{ 
    if (condition()) return bar(); 

    MyMethodThatAlwaysThrowsAnException("missed something."); 
} 
+0

Eso fue solo un simple ejemplo. El código real es bastante más complejo. – k0dek0mmand0

+0

@ k0dek0mmand0: sospechaba que ese podría ser el caso. Supongo que no tiene suerte, no hay forma de decirle al compilador que 'MyMethodThatAlwaysThrowsAnException' siempre arroja. – LukeH

1

Si no desea tener que establecer x, ¿por qué no utiliza simplemente un parámetro ref?

void foo(ref int x) 
{ 
    if(condition()) { x = bar(); return; } 

    // nobody complains about anything 

    MyMethodThatAlwaysThrowsAnException("missed something."); 
} 
2

Es un hilo muy antiguo, pero sólo quiero añadir que debe escribirlo diferente desde el principio:

void foo(out int x) 
{ 
    if (!condition()) 
     MyMethodThatAlwaysThrowsAnException("missed something."); 

    x = bar(); 
    // and so on... 
} 

De esa manera compilador no se quejará y su código es mucho más clara.

+0

El código real es probablemente más complejo, por lo que su sugerencia puede no tener sentido. –

Cuestiones relacionadas