2010-09-21 18 views
6

Después de escribir código que se puede reducir a lo siguiente:Justificación de OverflowException arrojado con tamaño de matriz negativo?

var size=-1; 
var arr=new byte[size]; 

Me sorprendió que se lanzó una OverflowException. La documentación para OverflowException Estado:

The exception that is thrown when an arithmetic, casting, or conversion operation in a checked context results in an overflow.

no pude ver cómo proporcionar un tamaño negativo para la longitud de la matriz y encaja en la descripción dada para esta excepción, por lo que profundizó un poco más y encontraron que este es el comportamiento especificado:

The computed values for the dimension lengths are validated as follows. If one or more of the values are less than zero, a System.OverflowException is thrown and no further steps are executed.

Me pregunto por qué se eligió OverflowException. Es bastante engañoso si me preguntas. Me costó al menos 5 minutos de investigación (sin contar mis meditaciones aquí). ¿Alguien puede arrojar alguna luz sobre esta (peculiar) decisión de diseño?

+0

Parece razonable arrojarme esta excepción. – cjk

+0

¿Cómo es un desbordamiento de cualquier descripción? – spender

Respuesta

8

Esto es casi seguro una optimización. El código del framework .NET es bastante religioso sobre la comprobación de argumentos para permitir que el programador caiga en la trampa del éxito. Pero eso no es gratis. El costo es bastante minúsculo, muchos métodos de clase toman muchos más ciclos de máquina de lo que se gasta en la verificación.

Pero las matrices son especiales. Son la estructura de datos básicos en el marco. Casi todas las clases de colecciones están construidas encima de ellas. Cualquier sobrecarga en la clase Array impacta directamente en la eficiencia de una gran cantidad de código que se encuentra encima. Evitar el control está bien, se verifica implícitamente de todos modos cuando el código interno necesita convertir el valor en unsigned. Y es muy raro que se dispare. Así que revisarlo dos veces no vale la pena el mejor mensaje de excepción.

1

Puede ser porque ese tamaño es un int sin firmar. Almacena el complemento de -1 en dos, que cuando se lo mira como un int sin signo, es el entero positivo máximo que se puede almacenar. Si este número es más grande que el tamaño posible de una matriz, se desbordará.

Advertencia: esto es pura especulación.

+0

Los tamaños de matriz, en .NET, se almacenan como Int32, no sin signo. Creo que esto se hizo para mantener las matrices CLS en conformidad. –

+0

Originalmente estaba pensando en estas líneas, pero la especificación es bastante específica de que es el tamaño negativo que causa esta excepción. – spender

5

OverflowException, en la documentación, básicamente define un desbordamiento como algo que:

produce un resultado que está fuera del rango del tipo de datos

En este caso, los valores negativos están fuera del rango válido para un tamaño de matriz (o realmente, cualquier tamaño).

Pude ver el argumento de que ArgumentOutOfRangeException podría ser, de alguna manera, mejor; sin embargo, no hay ningún argumento involucrado en una definición de matriz (ya que no es un método), por lo que tampoco sería una elección perfecta .

Cuestiones relacionadas