2009-10-16 23 views
39

Estaba haciendo algunas pruebas unitarias en el código que podría arrojar una serie de excepciones dependiendo de las entradas. Así que he intentado algo así como el código de abajo: (simplificado para el ejemplo)¿Por qué no puedo atrapar una excepción genérica en C#?

static void Main(string[] args) 
    { 
     RunTest<ArgumentException>(); 
    } 

    static void RunTest<T>() where T : Exception, new() 
    { 
     try 
     { 
      throw new T(); 
      //throw new ArgumentException(); <-- Doesn't work either 

     } 
     catch (T tex) 
     { 
      Console.WriteLine("Caught passed in exception type"); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("Caught general exception"); 
     } 
     Console.Read(); 
    } 

Pero esto siempre se imprimirá "excepción general Atrapados", la captura (T tex) manejador no va a funcionar. No importa si lanzo T() o lanzo explícitamente ArgumentException(). ¿Alguna idea de por qué es esto? En realidad, estaba un poco sorprendido de que incluso pudiera usar T en la cláusula catch, pero como eso es posible, ¿no debería funcionar? ¿O al menos dar un error/advertencia del compilador que diga que este controlador nunca funcionará?

Mi entorno es Visual Studio 2008 y 3.5 es el marco de destino.

ACTUALIZACIÓN: Lo intenté ahora directamente desde el símbolo del sistema y luego se imprime "Atrapado pasado en tipo de excepción". Por lo tanto, parece que esto está restringido para ejecutarse desde Visual Studio. ¿Tal vez una peculiaridad del proceso de alojamiento de Visual Studio?

+1

Acabo de prueba en LINQPad y se imprime Caught pasado en el tipo de excepción. ¿Puede dar más detalles de su entorno y la versión del marco? –

+2

Eso es interesante. Lo ejecuté como una aplicación de consola en VS2008 e imprimí una excepción general de Caught. –

+0

También funciona en la aplicación de consola SnippetCompiler –

Respuesta

32

Comportamiento extraño aquí ...

VS2k8 console app. En el siguiente:

try 
{ 
    throw new T(); 
} 
catch (T tex) 
{ 
    Console.WriteLine("Caught passed in exception type"); 
} 
catch (Exception ex) 
{ 
    Console.WriteLine("Caught general exception"); 
} 

resultados en "excepción general Atrapados".

Pero, eliminar las variables (inútiles) a partir de las declaraciones de capturas:

try 
{ 
    throw new T(); 
} 
catch (T) 
{ 
    Console.WriteLine("Caught passed in exception type"); 
} 
catch (Exception) 
{ 
    Console.WriteLine("Caught general exception"); 
} 

resultados en "Atrapado en el pasado Tipo de excepción" !!!


actualización:

heheh ... Es un error: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=362422&wa=wsignin1.0

Fuente? Aquí. Why does catch(TException) handling block behaviour differ under the debugger after installing Visual Studio 2008?

2

parecería que el tipo más específico de la excepción, cuando se administra la elección entre T y Excepción es una excepción, por lo que se invoca ese controlador.

Acabo de probar esto (no puede hacerlo en C# o VB, pero edité el IL), y cambié la segunda cláusula catch para detectar Object Ex en lugar de Exception Ex, y en ese caso, el primer controlador fue golpeado.

Editar

Como otros han señalado, es más que ver con el funcionamiento en el depurador que el tipo específico

Cuestiones relacionadas