2011-02-07 25 views
7

Tengo un problema para que TryParse funcione correctamente para mí. Tengo una lista de valores que, estoy seguro, son válidos (ya que provienen de otro componente de nuestro sistema) pero me gustaría asegurarme de que haya un correcto manejo de errores.Error de TryParse con números negativos

Aquí es una lista de ejemplo de mis valores:

20,00
20,00
-150,00

Y aquí es el método que originalmente escribió:

private decimal CalculateValue(IEnumerable<XElement> summaryValues) 
     { 
      decimal totalValue = 0; 

      foreach (XElement xElement in summaryValues) 
      { 
       decimal successful; 
       Decimal.TryParse(xElement.Value, out successful); 
       if (successful > 0) 
        totalValue += Decimal.Parse(xElement.Value); 
      } 
      return totalValue; 
     } 

La variable 'exitoso' devolvía falso por -150.00, así que agregué NumberStyles:

private decimal CalculateValue(IEnumerable<XElement> summaryValues) 
     { 
      decimal totalValue = 0; 

      foreach (XElement xElement in summaryValues) 
      { 
       decimal successful; 
       Decimal.TryParse(xElement.Value, NumberStyles.AllowLeadingSign, null, out successful); 
       if (successful > 0) 
        totalValue += Decimal.Parse(xElement.Value, NumberStyles.AllowLeadingSign); 
      } 
      return totalValue; 
     } 

Sin embargo, ahora que tengo NumberStyles allí, ¡ninguno de los números se analizará! Me siento bien con tener IFormatProvider establecido en nulo ya que todo esto está dentro de nuestro sistema. ¿Alguien ve lo que puedo estar haciendo mal?

+2

¿Por qué estás de análisis dos veces? – SLaks

Respuesta

3

Las otras respuestas tienen la idea correcta en cuanto a la forma correcta de usar Decimal.TryParse. Sin embargo, si estuviera escribiendo el método en cuestión, que haría uso de LINQ para trabajar con objetos LINQ to XML:

private decimal CalculateValue(IEnumerable<XElement> summaryValues) 
{ 
    return summaryValues 
     .Sum(el => 
      { 
       decimal value; 
       if (Decimal.TryParse(el.Value, out value)) 
        return value; 
       return 0M; 
      }); 
} 

Esta versión funciona de la misma manera, pero utiliza el método para calcular el Enumerable.Sum total. Todo lo que tengo que proporcionar es una función en línea que extrae valores decimales de un XElement.

+0

Gracias, terminé usando este código. – Jeannine

11

No se debe utilizar TryParse.

TryParse devuelve un valor lógico (verdadero/falso), por lo que su código debe ser:

private decimal CalculateValue(IEnumerable<XElement> summaryValues) 
     { 
      decimal totalValue = 0; 

      foreach (XElement xElement in summaryValues) 
      { 
       decimal valueReturned; 
       bool successful = Decimal.TryParse(xElement.Value, out valueReturned); 
       if (successful) 
        totalValue += valueReturned; 
      } 
      return totalValue; 
     } 

o más sucintamente,

private decimal CalculateValue(IEnumerable<XElement> summaryValues) 
     { 
      decimal totalValue = 0; 

      foreach (XElement xElement in summaryValues) 
      { 
       decimal valueReturned; 
       if (Decimal.TryParse(xElement.Value, out valueReturned)) 
        totalValue += valueReturned; 
      } 
      return totalValue; 
     } 
+1

'if (! Decimal.TryParse (/ * derp * /) arroja la nueva InvalidOperationException (" OMG WTF LOL ")' – Will

+0

@Will En este ejemplo, debería tener una excepción como esta, _incluso si_ él confía razonablemente en la fuente. podría tener una situación en la que espera y desea ignorar silenciosamente cadenas que no analizan. –

1

su éxito va a ser negativo para un valor negativo siendo analizado. su if (successful > 0) es lo que le está haciendo tropezar.

Si van casi de manera positiva a ser valores válidos, trate de usar Convert.ToDecimal:

decimal val = Convert.ToDecimal(xElement.Value); 

De lo contrario, cambiar la lógica un poco para ser más como:

decimal val; 
if (Decimal.TryParse(xElement.Value, out val)){ 
    // valid number 
} 
0

que habría que sugeriría Dile a XElement qué valor de nodo debe buscar como en:

XElement.Element("nodename").Value 

Instea d de XElement.Value. al menos eso es lo que haría :)

4

Otros están explicando cómo hacerlo bien, pero no explicando realmente lo que está haciendo mal.

Donde está utilizando "exitoso" arriba no es el valor de éxito, es el número real que se está analizando. Entonces, si está analizando "-150.00", por supuesto, será negativo. El valor de salida de TryParse es el valor analizado real y el booleano que indica si el proceso fue exitoso o no es el valor devuelto. El uso de lo que tiene que ayudar a entender sería algo así como:

string inputValue = "-150.00"; 
decimal numericValue; 
bool isSucessful = Decimal.TryParse(inputValue , out numericValue); 

En este caso, isSuccessful será cierto, NumericValue será -150.Cuando usted está utilizando los valores proporcionados por el usuario en lugar de la hardcoded utilicé por encima de usted querrá comprobar:

if(isSuccessful) 
{ 
    // Do something with numericValue since we know it to be a valid decimal 
} 
else 
{ 
    // Inform User, throw exception, etc... as appropriate, Don't use numericValue because we know it's wrong. 
} 
+0

Sí, esta fue la raíz del problema. Gracias por educarme :) – Jeannine

0

Entra en Google. La respuesta para mí fue que la cultura entrante estaba equivocada, específicamente en un archivo JSON entrante.

Uso

totalValue += decimal.Parse(xElement.Value, NumberStyles.Any, CultureInfo.InvariantCulture); 

o

bool successful = decimal.TryParse(xElement.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out value); 
Cuestiones relacionadas