2010-07-12 23 views
6

Creé un pequeño programa que calcula el promedio de 15 números o menos. Hay 15 cuadros de texto, el valor predeterminado de cada uno es '0'. El programa sabe para obtener la suma de todos los números escritos y dividirlo por números de cuadros de texto que no devuelven '0'. Pero si el usuario borra por error uno de los '0'os en uno de los cuadros de texto ... error de tiempo de ejecución.Cómo convertir null en 0

Originalmente resolvieron este problam escribiendo esta "sentencia if " 15 veces (una para cada cuadro de texto):

if (t1.Text == "") { tr1 = 0; } 
else 
{ 
    tr1 = Double.Parse(t1.Text); 
} 

comprueba este código si no hay una cosa en la caja de texto (por ejemplo, llamado t1), si es verdadero, el programa da doble 'tr1' (no confunda con 't1'), el valor de '0', si es falso, el código da doble ' tr1 'el texto de' t1 '.

tuve que escribir esto 'si' 15 veces. Quería saber si puedo escribir el mismo código con matrices y un ciclo for, ¿y cómo?

aquí es todo el código (lo siento por los nombres var no son similar al uso de var.):

private void goyouidiot_Click(object sender, EventArgs e) 
{ 
    double tr1; 
    double tr2; 
    double tr3; 
    double tr4; 
    double tr5; 
    double tr6; 
    double tr7; 
    double tr8; 
    double tr9; 
    double tr10; 
    double tr11; 
    double tr12; 
    double tr13; 
    double tr14; 
    double tr15; 
    if (t1.Text == "") { tr1 = 0; } 
    else 
    { 
     tr1 = Double.Parse(t1.Text); 
    } 
    if (t2.Text == "") { tr2 = 0; } 
    else 
    { 
     tr2 = Double.Parse(t2.Text); 
    } 

    if (t3.Text == "") { tr3 = 0; } 
    else 
    { 
     tr3 = Double.Parse(t3.Text); 
    } 


    if (t4.Text == "") { tr4 = 0; } 
    else 
    { 
     tr4 = Double.Parse(t4.Text); 
    } 


    if (t5.Text == "") { tr5 = 0; } 
    else 
    { 
     tr5 = Double.Parse(t5.Text); 
    } 

    if (t6.Text == "") { tr6 = 0; } 
    else 
    { 
     tr6 = Double.Parse(t6.Text); 
    } 


    if (t7.Text == "") { tr7 = 0; } 
    else 
    { 
     tr7 = Double.Parse(t7.Text); 
    } 


    if (t8.Text == "") { tr8 = 0; } 
    else 
    { 
     tr8 = Double.Parse(t8.Text); 
    } 

    if (t9.Text == "") { tr9 = 0; } 
    else 
    { 
     tr9 = Double.Parse(t9.Text); 
    } 


    if (t10.Text == "") { tr10 = 0; } 
    else 
    { 
     tr10 = Double.Parse(t10.Text); 
    } 


    if (t11.Text == "") { tr11 = 0; } 
    else 
    { 
     tr11 = Double.Parse(t11.Text); 
    } 


    if (t12.Text == "") { tr12 = 0; } 
    else 
    { 
     tr12 = Double.Parse(t12.Text); 
    } 

    if (t13.Text == "") { tr13 = 0; } 
    else 
    { 
     tr13 = Double.Parse(t13.Text); 
    } 


    if (t14.Text == "") { tr14 = 0; } 
    else 
    { 
     tr14 = Double.Parse(t14.Text); 
    } 


    if (t15.Text == "") { tr15 = 0; } 
    else 
    { 
     tr15 = Double.Parse(t15.Text); 
    } 
    double[] sch = { tr1, tr2, tr3, tr4, tr5, tr6, tr7, tr8, tr9, tr10, tr11, tr12, tr13, tr14, tr15 }; 
    double total = 0; 
    double sorf = 0; 
    for (int i = 0; i != 14; i++) 
    { 

     sorf = sorf + sch[i]; 

     if (sch[i] > 0) 
     { total++; } 

    } 

    double totalic = sorf/total; 
    string glass = totalic.ToString(); 
    result.Text = ("your score: " + glass); 
} 
+0

¿Qué sucede si el usuario ingresa un cero en una de las casillas? ¿No terminarías calculando el promedio incorrecto? – Shravan

+0

Usaría try/catch en lugar de esos casos if/else. Esto se debe a que el usuario también puede ingresar texto, lo que provocará una excepción, cuando intente utilizar Double.Parse (tx.Text) ;. – Biroka

+7

Código de copiar/pegar, Batman! – cHao

Respuesta

10
Double.TryParse(t1.Text.Trim(), out tr1); 

fijará TR1 al valor numérico de la caja de texto, o 0.0 si no pudo convertir por alguna razón. También devolverá true si la conversión fue exitosa o falsa si falló, pero no le importa el valor de retorno si el valor predeterminado es 0.0.

Bonificación adicional: no arrojará una excepción si alguien decide poner "Esto no es un número". en un cuadro de texto. Es solo verá el valor como 0.

Para hacer esto en una serie ...

TextBox t[] = { t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15 }; 
double tr[] = new double[t.Length]; 

for (int i = 0; i < t.Length; ++i) 
{ 
    Double.TryParse(t[i].Text.Trim(), out tr[i]); 
} 

ACTUALIZACIÓN:

Nota, es perfectamente razonable esperar ser capaz de calcular un promedio de números que incluye 0. con el fin de hacer esto:

TextBox t[] = { t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15 }; 
double tr[] = new double[t.Length]; 
int valid_count = 0; 

for (int i = 0; i < t.Length; ++i) 
{ 
    if (Double.TryParse(t[i].Text.Trim(), out tr[i])) ++valid_count; 
} 

Establecer valores predeterminados sus cuadros de texto en blanco (''), y entonces sabrá cuántos eran legítimamente de 0 introducido por el usuario y el número de estaban en blanco. Divida la suma por valid_count para obtener un promedio preciso. (Pero asegúrese valid_count > 0, o probablemente obtendrá una excepción de división por cero.)

0

Ponga una .trim() para recuperar los valores del cuadro de texto

tr3 = Doble .Parse (t3.Text.Trim());

+0

¿cómo puedo usarlo para resolver mi problema? qué .trim() hace de todos modos? hay un error en tiempo de ejecución como intenté convertir null en 0 –

7

Claro, haga un double tr[15] y una matriz correspondiente de campos de texto.

Entonces sólo tiene que utilizar:

for (int i = 0; i < 15; i++) { 
    if (t[i].Text == "") { 
     tr[i] = 0; 
    } else { 
     tr[i] = Double.Parse(t[i].Text); 
    } 
} 
3

Si es sólo la gran cantidad de código fuente se recogió con sus if declaraciones, se puede optar por algo como:

tr1 = (t1.Text == "") ? 0 : Double.Parse(t1.Text); 
tr2 = (t2.Text == "") ? 0 : Double.Parse(t2.Text); 
: 
tr15 = (t15.Text == "") ? 0 : Double.Parse(t15.Text); 

Ésta es agradable y limpio , no ocupa mucho espacio en pantalla y es bastante fácil ver el intento.

O, mejor aún, algo así como:

tr1 = 0; try { tr1 = Double.Parse(t1.Text); } catch (Exception e) {}; 
tr2 = 0; try { tr2 = Double.Parse(t2.Text); } catch (Exception e) {}; 
: 
tr15 = 0; try { tr15 = Double.Parse(t15.Text); } catch (Exception e) {}; 

debido a que los campos podrían ser inválida y no esté en blanco.

Usted puede hacer lo mismo con matrices y un bucle for si la estructura de sus datos y controles de manera diferente, pero puede que no sea necesario para sólo quince artículos. Ciertamente, si agregaras más, consideraría seriamente esa opción.

Y es posible que desee cargar los valores directamente en una matriz de modo que no es necesario sch:

double tr[15]; 
: 
tr[ 0] = 0; try { tr[ 0] = Double.Parse(t1.Text); } catch (Exception e) {}; 
tr[ 1] = 0; try { tr[ 1] = Double.Parse(t2.Text); } catch (Exception e) {}; 
: 
tr[14] = 0; try { tr[14] = Double.Parse(t15.Text); } catch (Exception e) {}; 
: 
double total = 0; 
double sorf = 0; 
for (int i = 0; i < 15; i++) { 
    if (tr[i] > 0) { 
     sorf = sorf + tr[i]; 
     total++; 
    } 
} 
: 

Para una solución código mínimo , también puede crear una matriz de los cuadros de texto de donde extraes la informaciónAlgo así como (no probado):

TextBox t[] = {t1, t2, t3, ..., t15}; 
double tr[t.length]; 
: 
for (int i = 0; i < t.length; i++) { 
    tr[i] = 0; try { tr[i] = Double.Parse(t[i].Text); } catch (Exception e) {}; 
} 
: 
double total = 0; 
double sorf = 0; 
for (int i = 0; i < tr.length; i++) { 
    if (tr[i] > 0) { 
     sorf = sorf + tr[i]; 
     total++; 
    } 
} 
: 
+1

Tiene 90k rep y nunca se le ocurre hacer una función 'ParseDoubleOrZero'? – Gabe

+1

Tengo un representante de 90 K pero soy un recién llegado relativo a C# :-) Pero tu punto es claro, aunque me pregunto cuánto de ventaja tiene. Ciertamente ninguno en términos del tamaño del código fuente. Probablemente menos código objeto y más legible ya que podría usar un nombre de función decente. – paxdiablo

+0

Y usaría double.TryParse en su lugar porque las excepciones surgirán regularmente si es un usuario que ingresa un número. –

2

escribir una función que convierte un valor de cuadro de texto a un doble, algo así como:

private static double ConvertTextboxValueToDouble(string value) 
{ 
    double result; 
    Double.TryParse(value, out result); 

    return result; 
} 

A continuación, crear una matriz a partir de los cuadros de texto, convertir sus valores a los dobles:

double[] values = 
    { 
     ConvertTextboxValueToDouble(t1.text), 
     ConvertTextboxValueToDouble(t2.text), 
     ConvertTextboxValueToDouble(t3.text), 
... 
     ConvertTextboxValueToDouble(t15.text) 
    } 
1

¿Ha considerado el uso de un NumericUpDown en lugar de un cuadro de texto?

También en lugar de escribir algo quince veces que realmente debe refactorizar el código y probar una de las siguientes maneras:

  • Registro para todos sus cuadros de entrada de un evento, donde todos usando el mismo código

    public void ValueChanged(Object sender, EventArgs e) 
    { 
        var numericUpDown = sender as NumericUpDown; 
        if(numericUpDown == null) 
         return; 
        //ToDo: Put some check code here 
    } 
    
  • uso alguna List<T> donde poner todas sus cajas en e iterar sobre ella para comprobar todos los ajustes

    var myList = new List<NumericUpDown>(); 
    //ToDo: Put all your boxes into it 
    myList.Add(numericUpDown1); 
    myList.Add(numericUpDown2); 
    //or get the list from somewhere else 
    myList.AddRange(this.Controls.OfType<NumericUpDown>()) 
    
    //OnButtonClick 
    foreach(var numericUpDown in myList) 
    { 
        //ToDo: Do some checking 
    } 
    
+0

numricupdown no ayudará en los casos de averege de los números 100, 97, 34. el usuario obtendrá el nivel de encontrar el número. –

+0

no entiendo tu comentario. Un NumericUpDown es un TextBox que solo acepta números más dos botones para ingresar/disminuir el valor. Entonces, el usuario puede usar estos botones, pero también puede ingresar directamente estos valores, como en un cuadro de texto. – Oliver

+0

Así que no veo por qué debería usar NumricUpDown. –

0

Para estas situaciones y pensando en realizar el trabajo en una pequeña porción de código, utilizo un pequeño truco sucio: poner los controles en un panel.

Si el grupo especial sólo se contiene controles deseados (en este caso), cuadros de texto, esto será suficiente para almacenar los valores de una lista de dobles:

private void button1_Click(object sender, EventArgs e) 
    { 
     List<double> doubleList = new List<double>(); 

     foreach (TextBox t in panel1.Controls) 
      doubleList.Add(this.checkTextBox(t)); 
    } 

    private double checkTextBox(TextBox t) 
    { 
     return (t.Text != string.Empty) ? Double.Parse(t.Text.Trim()) : 0; 
    } 

Si no se puede tener solamente un panel para cuadros de texto y la fuerza de diseño que le permite mezclar los controles en, usted tendrá que hacer una comprobación/conversión adicional:

private void button1_Click(object sender, EventArgs e) 
    { 
     List<double> doubleList = new List<double>(); 

     foreach (Control t in panel1.Controls) 
      if(t is TextBox) 
       doubleList.Add(this.checkTextBox((TextBox)t)); 
    } 

    private double checkTextBox(TextBox t) 
    { 
     return (t.Text != string.Empty) ? Double.Parse(t.Text.Trim()) : 0; 
    } 

saludos!

Cuestiones relacionadas