2012-09-27 3 views
16

? Tan solo por curiosidad, quería ver qué era especial acerca de la clase de excepción que permitía usarla con la palabra clave Throw, mientras que una clase estándar no lo es.¿Por qué un tipo arrojado o atrapado se deriva de System.Exception

Todo lo que encontré es que la clase de excepción previstos los siguientes

public class Exception : System.Object, System.Runtime.Serialization.ISerializable, System.Runtime.InteropServices._Exception 
{ 
} 

así que traté de aplicar esas mismas interfaces e intentar tirar mi propia excepción personalizada que no se derivan de System.Exception en vano. Simplemente estaba informaron de que

El tipo agarrado o lanzado deben derivarse de System.Exception

Entonces, ¿hay alguna razón específica para esto? Supongo que hay pocas opciones en los idiomas administrados que parecen arbitrarias.

+0

Creo que para averiguar cómo funciona, tendría más sentido echar un vistazo a la implementación de 'throw' en lugar de la clase' Exception'. – Guillaume

+0

Bastante pero, sinceramente, no tengo ni idea de dónde empezar a hacer eso ... –

Respuesta

18

Creo que su premisa es errónea. Es posible que se arroje un objeto que no se deriva de System.Exception. No se puede tirar en C# ni examinar el objeto en una cláusula catch. Desde la sección 8.10 de la C# spec (v4.0):

Algunos lenguajes de programación pueden apoyar excepciones que no son representable como un objeto derivado de System.Exception, aunque tales excepciones nunca podrían ser generados por código C# . Se puede utilizar una cláusula de captura general para detectar tales excepciones. Por lo tanto, una cláusula catch general es semánticamente diferente de una que especifica el tipo System.Exception, en el que el primero también puede detectar excepciones de otros idiomas.

Un ejemplo de una captura en general:

try 
{ 
} 
catch (Exception) { } // 'specific' catch 
catch { } // 'general' catch 

En particular, esto es importante cuando se llama a código no administrado.

Algunos tipos siempre parecen recibir un trato especial en todos los idiomas. Principalmente porque son tan fundamentales para el sistema. System.Exception, System.ValueType, System.Delegate son todos tipos especiales en C# que están estrechamente ligados a las palabras clave del lenguaje y al CLR, por lo que no es sorprendente que no pueda implementar clases que se hagan cargo de sus funciones.

+1

Guau, no sabía eso, muchas gracias por ampliar mi comprensión ... –

+0

+1 He leído bastante las especificaciones de C#, pero nunca vi (o al menos nunca entendí por completo el significado de) ese pasaje Mi upvote te pone en el representante de 1999, veré si puedo encontrar algo más para votar sobre 2000. – phoog

4

El idioma usa System.Exception como base para todas las excepciones. Esto significa esencialmente que cualquier excepción arrojable o atrapable no debería dar error si lo hace (Exception)myExc. Esto es probablemente porque se usa la definición de la clase System.Exception para que todas las excepciones se adhieran a la misma interfaz. Debido a la interfaz coherente, las excepciones llegan con un seguimiento de la pila y un mensaje significativo (por ejemplo), que es muy valioso para el registro.

9

Design Guidelines for Exceptions

excepciones son el mecanismo estándar para informar de errores. Las aplicaciones y las bibliotecas no deben usar códigos de retorno para comunicar errores. El uso de las excepciones se suma a un diseño de marco consistente y permite que los informes de errores de los miembros, como constructores, que no se puede tener un tipo de retorno

throw (C# Reference)

la excepción lanzada es un objeto cuya clase se deriva de System.Exception, como se muestra en el siguiente ejemplo.

class MyException : System.Exception {} 
// ... 
throw new MyException(); 

Exceptions Overview

En .NET Framework, una excepción es un objeto que hereda de la clase de excepción

lo tanto, su excepción debe derivar de System.Exception, pero Depende de usted, cómo lo organiza dentro.

4

Es una elección arbitraria de los diseñadores del CLS. Presumiblemente hicieron esta elección por razones de consistencia. C# sigue al CLS; el compilador aplica el requisito por este motivo, no por ninguna razón técnica relacionada con la implementación del tipo de excepción.

La CLI puede arrojar cualquier objeto. Ver http://jilc.sourceforge.net/ecma_p3_cil.shtml#_Toc524462405.

3

Una razón por la cual cada excepción necesita tener una clase base universal es para que pueda detectar cada tipo de excepción en un único bloque catch.

Si tengo esto:

try 
{ 
    ... 
} 
catch(Exception ex) 
{ 
    // Handle somehow 
} 

que captura todas las excepciones, y me permitirá muestro lo que es (mediante el uso de ex.Message).

Si pudiera arrojar cualquier cosa, entonces, ¿cómo podría tener una captura que capturaría todo y aún le daría acceso al objeto arrojado?

usted podría tener esto, que cogerá absolutamente todo:

try 
{ 
    ... 
} 
catch 
{ 
    // Handle somehow 
} 

Pero se han 'perdido' la cosa que fue lanzada.

+0

¿Y qué hay de la captura (objeto o)? Esto probablemente no sea suficiente cuando se interopera con C++, pero esta no debería ser una razón para evitar tirar algo más. –

Cuestiones relacionadas