2010-07-15 8 views
8

Vengo de un fondo en su mayoría C/C++ antes de comenzar a usar C#. Una de las cosas que hice con mi primer proyecto en C# fue hacer una clase como esta¿Por qué los tipos de CLR sin firmar son tan difíciles de usar en C#?

class Element{ 
    public uint Size; 
    public ulong BigThing; 
} 

entonces yo estaba mortificado por el hecho de que esto requiere de calidad:

int x=MyElement.Size; 

al igual que

int x=5; 
uint total=MyElement.Size+x; 

¿Por qué los diseñadores de idiomas decidieron hacer que los tipos de entero con signo y sin signo no se moldeen implícitamente? ¿Y por qué los tipos sin firmar no se usan más en toda la biblioteca .Net? Por ejemplo, String.Length nunca puede ser negativo, sin embargo, es un número entero con signo.

+1

Incluso en C++ un lanzamiento de unsigned a signed o back provoca una advertencia. –

+0

@Seva según el compilador: P .. Me doy cuenta de que mi primer caso es débil, pero mi segundo caso es más lo que quiero decir porque no hay posibilidad de pérdida de datos a menos que 'x' sea negativo – Earlz

+0

En el segundo recuento , mira mi respuesta a continuación ... –

Respuesta

18

¿Por qué los diseñadores de idiomas decidieron convertir implícitamente los tipos de entero con signo y sin signo ?

Porque eso podría perder datos o arrojar cualquier excepción, ninguno de los cuales es generalmente algo bueno que permitir implícitamente. (La conversión implícita de largo para duplicar puede perder datos demasiado, es cierto, pero de una manera diferente.)

Y por qué son los tipos sin signo que no se usan más en toda la biblioteca .Net

tipos sin signo no son compatibles con CLS, no todos los lenguajes .NET siempre han sido compatibles. Por ejemplo, Visual Basic no tenía soporte "nativo" para tipos de datos sin signo en .NET 1.0 y 1.1; fue agregado al lenguaje para 2.0. (Todavía podría usarlos, pero no eran parte del lenguaje en sí; no podía usar los operadores aritméticos normales, por ejemplo).

+3

"aunque podría estar equivocado" - ¿Quiere decir que .NET pudo haberse equivocado? – PostMan

+0

@PostMan: Acabo de encontrar un poco más de información ... se editará. –

1

Porque convertir implícitamente un entero sin signo de 3B en un entero con signo va hacer estallar.

Sin firmar tiene el doble del valor máximo de firmado. Es la misma razón por la que no puedes lanzar un anhelado int.

+0

¿Alguien con suficiente reputación para editar puede corregir eso para decir "entero sin signo de 3B en un entero con signo?" Su intención era clara, solo un error tipográfico. –

+0

Gracias Dave, incluso lo volví a leer y lo perdí: x –

4

Junto con la respuesta de Jon, el hecho de que un número sin firmar no pueda ser negativo no significa que no sea más grande que uno firmado. uint es 0 a 4,294,967,295 pero int es -2,147,483,648 a 2,147,483,647. Mucho espacio por encima de int como máximo de pérdida.

0

En el segundo recuento: porque querían que el CLR fuera compatible con los idiomas que no tienen tipos de datos sin signo (léase: VB.NET).

+0

VB.net ha tenido números sin firmar desde al menos 2.0. No sabía que faltaban antes, pero eso tendría mucho sentido: no estaban en VB a tiempo para convertirlo en CLS. – cHao

+0

Pero cambiar la clase String en .NET v2 (o, para el caso, alguna vez) rompería una gran cantidad de código. –

1

entonces yo estaba mortificado por el hecho de que esto requiere de calidad:

int x=MyElement.Size; 

Pero se contradice aquí. Si realmente (realmente) necesita que el Tamaño no esté firmado en lugar de asignarlo a (firmado) x es un error. Un profundo error en tu código.

Por ejemplo Cadena.Longitud nunca puede ser negativo, sin embargo, es un entero con signo

Pero String.IndexOf puede devolver un número negativo, y sería muy conveniente si los valores y String.length índice donde de diferentes tipos.

Y si bien en teoría habría un mérito en un String.Length sin firmar (4 GB de límite), en la práctica incluso los 2 GB actuales son lo suficientemente grandes (porque las cadenas de esa longitud son raras e impracticables).

Así que la verdadera respuesta es: ¿Por qué usar unsigned en primer lugar?

+0

Bueno, ¿porque permite una expresión más amplia de números sin firmar? –

+0

@Henk: creo que un mejor ejemplo de donde usar 'int' es incómodo es' Array.Length'. Uno nunca esperaría que una matriz tenga un tamaño negativo, y usar un tipo con signo limita el tamaño (informado) de la matriz a poco menos de 2 GB. Además, los índices de matriz nunca pueden ser negativos. Ahora bien, está la propiedad 'LongLength' que informa el tamaño de la matriz como' Int64', pero aún así lo informa como un valor firmado. La consideración primordial en estos casos es el hecho de que los diseñadores de .NET eligieron hacer que los tipos sin firmar no sean compatibles con CLS. Algo que es poco probable que cambie alguna vez en este punto. – LBushkin

+0

@Paul: 'decimal' tiene un rango aún más amplio. La pregunta es para usos prácticos de unsigned. El OP no ha proporcionado ninguno. –

Cuestiones relacionadas