2009-04-13 14 views
57

Pregunta simple: ¿por qué el tipo Decimal define estas constantes? ¿Por qué molestarse?¿Cuál es el propósito de Decimal.One, Decimal.Zero, Decimal.MinusOne en .Net

Estoy buscando una razón por la cual esto se define por el lenguaje, no es posible utilizar o efectos en el compilador. ¿Por qué poner esto allí en primer lugar? El compilador puede fácilmente en línea 0m como podría Decimal.Zero, así que no lo estoy comprando como un atajo de compilación.

+0

No creo que estas respuestas explican adecuadamente por qué estos valores están ahí. Estoy escuchando algunos efectos y el uso, pero lo que estoy buscando es ¿POR QUÉ fue diseñado en el idioma, y ​​por qué no está allí en Float, por ejemplo, o Int32 ... – Jasmine

Respuesta

27

Pequeña aclaración. En realidad, son valores estáticos de solo lectura y no constantes. Eso tiene una clara diferencia en .Net porque los valores constantes son en línea por varios compiladores y, por lo tanto, es imposible rastrear su uso en un ensamblado compilado. Sin embargo, los valores estáticos de solo lectura no se copian sino que se referencian. Esto es ventajoso para su pregunta porque significa que el uso de ellos puede analizarse.

Si usa el reflector y profundiza en el BCL, observará que MinusOne y Zero solo se utilizan en el tiempo de ejecución de VB. Existe principalmente para servir conversiones entre valores decimales y booleanos.Por qué MinusOne se utiliza casualmente surgió en un hilo separado hoy (link)

Por extraño que parezca, si nos fijamos en el valor Decimal.One notará que no se usa en ninguna parte.

En cuanto a por qué están explícitamente definidos ... Dudo que haya una razón difícil y rápida. Hay que aparece como un rendimiento específico y solo como una medida de conveniencia que se puede atribuir a su existencia. Mi conjetura es que fueron añadidos por alguien durante el desarrollo del BCL para su conveniencia y nunca fueron eliminados.

EDITAR

se clavaron en el tema const un poco más después de un comentario de @Paleta. La definición de C# de Decimal.One utiliza el modificador const, sin embargo se emite como static readonly en el nivel IL. El compilador C# usa un par de trucos para hacer que este valor sea prácticamente indistinguible de un const (literales en línea, por ejemplo). Esto se mostraría en un lenguaje que reconozca este truco (VB.Net lo reconoce pero F # no).

+0

no es cierto que esos valores son de sólo lectura, mirando el marco .NET metada decimal se puede ver la siguiente [DecimalConstant (0, 0, 4294967295, 4294967295, 4294967295)] \t \t decimal public const = MaxValue 79228162514264337593543950335m; [DecimalConstant (0, 128, 0, 0, 1)] \t \t public const decimal MinusOne = -1m; – Paleta

+0

@Paleta, no son 'readonly'. Lo he verificado mirando los metadatos y la página de MSDN para los valores hte. http://msdn.microsoft.com/en-us/library/system.decimal.one(VS.80).aspx – JaredPar

+0

Tengo que estar en desacuerdo con usted y su respuesta, mire el código reflejado mscorlib.dll aquí http: //reflector.webtropy.com/default.aspx/[email protected]/[email protected]/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/clr/src/BCL/System/[email protected]/1305376/[email protected] las declaradas como constantes, MSDN es incorrecto – Paleta

-3

Mi opinión en él es que están ahí para ayudar a evitar números mágicos.

Los números mágicos son básicamente en cualquier parte de su código que tiene un número aribtrary flotando alrededor. Por ejemplo:

int i = 32; 

Esto es problemático en el sentido de que nadie puede decir qué i es conseguir crear a 32, o lo que significa 32, o si debe ser de 32 en absoluto. Es mágico y misterioso.

En una línea similar, que verá a menudo código que hace esto

int i = 0; 
int z = -1; 

Por qué están siendo puesto a 0 y -1? ¿Es esto solo una coincidencia? ¿Significan algo? ¿Quién sabe?

Mientras Decimal.One, Decimal.Zero, etc no te dicen lo que significan los valores en el contexto de su aplicación (tal vez cero significa "perdido", etc.), que no usted que el valor se ha establecido deliberadamente decir, y probablemente tenga algún significado.

Aunque no es perfecto, esto es mucho mejor que no le dice nada en absoluto :-)

Nota Es no para la optimización. Observar este código C#:

public static Decimal d = 0M; 
public static Decimal dZero = Decimal.Zero; 

Al mirar el código de bytes generada usando ildasm, ambas opciones resultan en idéntica MSIL. System.Decimal es un tipo de valor, por lo que Decimal.Zero no es más "óptimo" que simplemente usar un valor literal.

+0

Más información: http: // gregbeech.com/blogs/tech/archive/2008/07/07/emitting-decimal-pseudo-constants-with-reflection-emit.aspx – boj

+1

Pero no hay propiedad Int32.Zero ... – Guffa

+0

Tu argumento me duele la cabeza. Son números, solo se convierten en números mágicos cuando comienzas a asociarles un significado aleatorio, como -1 significa lavar los platos y 1 significa hornear pasteles. Decimal.Uno es tan mágico como 1, pero podría decirse que es más difícil de leer (pero tal vez más óptimo). –

20

Algunos lenguajes .NET no admiten decimal como un tipo de datos, y es más conveniente (y más rápido) en estos casos escribir Decimal.ONE en lugar de Decimal nuevo (1).

La clase BigInteger de Java también tiene ZERO y ONE, por el mismo motivo.

+1

¿Alguien me puede explicar esto? 6 votos significa que tiene que ser una buena respuesta, pero: ¿Cómo se beneficia un lenguaje .Net que no admite decimal como un tipo de datos de tener una propiedad de solo lectura compartida que devuelve un decimal y se define como parte de la clase decimal? –

+7

Probablemente quiso decir que si un idioma no tiene literales decimales, usar una constante sería más eficiente que convertir un literal literal a un decimal. Todos los lenguajes .NET son compatibles con el tipo de datos System.Decimal, es parte del CLR. – Niki

+1

sí, Niki, eso es lo que quería decir. Por supuesto, puede usar System.Decimal en todos los lenguajes .NET, pero algunos lo soportan mejor (como C# que tiene una palabra clave decimal y literales decimales) y algo peor. Lo siento, el inglés no es mi lengua materna ... – mihi

-4

Esos 3 valores arghhh !!!

Creo que puede tener algo que ver con lo que yo llamo de cola de

decir que tiene esta fórmula 1:

(x) 1,116666 + (y) = (z) 2.00000

pero x, z se han redondeado a 0,11 y 2.00, y se le pide que calcule (y).

por lo que puede pensar y = 2.00 - 1.11. En realidad, y es igual a 0,88 pero obtendrá 0,89. (hay un 0.01 en la diferencia).

depende del valor real de x e y los resultados varía de -0.01 a 0,01, y en algunos casos cuando se trata de un montón de aquellos detrás de 1, y para facilate cosas, se puede comprobar si el valor final es igual a Decimal.MinusOne/100, Decimal.One/100 o Decimal.Zero/100 para solucionarlos.

así es como los he usado.

+5

¿De qué estás hablando? ¿Estás haciendo mal las matemáticas con valores inexactos y luego usando el operador de división para crear tu épsilon? ¿Qué te hace pensar que el resultado siempre estará desactivado exactamente en 0.01, y no (por ejemplo) 0.005? Si estos valores representan dinero, me da miedo hacer negocios con su aplicación. –

+0

:) No estoy calculando un resultado final, tengo que dar el valor de (y) para el formato redondeado. como lo haras ? – Hassen

Cuestiones relacionadas