2011-08-17 20 views
12

En mi programa, estoy recorriendo una tabla de datos para obtener datos de cada campo. Una línea de mi código es el siguiente:¿Convertir el campo nulo a cero antes de convertir a int?

int LYSMKWh = Convert.ToInt32(resultsDT.Rows[currentRow]["LYSMKWh"]); 

Básicamente, sólo estoy tomando el valor que está en la célula y su conversión a int32. Me encuentro con un problema, sin embargo, cuando los datos en el campo son nulos. Aparece un mensaje de error de Cast inválido sobre no poder convertir un "DBNull" a otro tipo.

Por lo tanto, sé que solo puedo comprobar el valor del campo antes de tratar de convertirlo haciendo algo como esto:

if (resultsDT.Rows[currentRow]["LYSMKWh"] == null) 
      { 
       resultsDT.Rows[currentRow]["LYSMKWh"] = 0; 
      } 

Pero, ¿existe una mejor manera de hacer esto? ¿Hay algo que pueda hacer "en línea" mientras trato de convertir el valor sin tener que recurrir al uso del if?

EDIT: Yo probé el uso de este método sugerido:

int LYSMKWh = Convert.ToInt32(resultsDT.Rows[currentRow]["LYSMKWh"] ?? "0"); 

Por desgracia, todavía recibido el mensaje de error moldeada no válida en lo que respecta al tipo DBNull. Se sugirió que podría tener problemas para usar el ?? operador si los tipos de cada lado eran diferentes.

Además, dado que tengo control total sobre los datos con los que estoy construyendo mi datatable, los cambié para que no se escriban valores nulos en ningún campo. Entonces, eso prácticamente niega la necesidad de convertir un nulo a un int32, en este caso. Gracias por todos los consejos, ¡a todos!

Respuesta

9

Usted puede hacer esto:

var LYSMKWh = 
    resultsDT.Rows[currentRow]["LYSMKWh"].Equals(DBNull.Value) 
    ? 0 
    : Convert.ToInt32(resultsDT.Rows[currentRow]["LYSMKWh"]); 
+0

Esto realmente funcionó bastante bien para mí. Traté de usar los ejemplos a continuación con el ?? operador, pero igual terminé recibiendo el mensaje de error Recopilación inválida. ¿De qué usuario dijo CodeNaked a continuación, podrían surgir problemas al usar el ?? si los tipos de cada lado son diferentes. – Kevin

3

Puede considerar el uso del operador ?? de C#, que comprueba un valor para nulo y, si es nulo, le asigna un valor predeterminado.

+4

Un ejemplo podría ser 'int LYSMKWh = Convert.ToInt32 (resultsDT.Rows [currentRow] [ "LYSMKWh"] ?? 0);' –

+0

cayeron en el La misma trampa, solo si el tipo de resultsDt.Rows [...] [...] es int (o cualquier número con auto conversión de 0), pero entonces Convert.ToInt32 no tendría sentido - supongo que es una cadena ? – Carsten

+1

tiene razón ... si OP tiene el control de la base de datos, tal vez pueda configurarlo para que devuelva nulo, y eliminar la primera parte del código (la que toma y convierte a int) por completo. debería funcionar bien ... –

0

Comprobar si es DBNull.Value en lugar de null:

if (resultsDT.Rows[currentRow]["LYSMKWh"] == DBNull.Value) 
{ 
    resultsDT.Rows[currentRow]["LYSMKWh"] = 0; 
} 

La expresión ternaria sería el siguiente:

var LYSMKwhField = resultsDT.Rows[currentRow]["LYSMKWh"]; 
int LYSMKWh = LYSMKwhField != DBNull.Value ? Convert.ToInt32(rowData) : 0; 
5

utilice el ?? operador:

resultsDT.Rows[currentRow][...] ?? "0" 

(esperando el campo para ser una cadena - si no cambian el "0")

0

Puede utilizar el ?? operador:

object x = null; 

int i = (int)(x ?? 0) 
1

Puede sustituirlo por un operador ternario:

var rowData = resultsDT.Rows[currentRow]["LYSMKWh"]; 
int LYSMKWh = rowData != null ? Convert.ToInt32(rowData) : 0; 

Alternativamente, el operador podría funcionar ??:

int LYSMKWh = Convert.ToInt32(resultsDT.Rows[currentRow]["LYSMKWh"] ?? 0); 

Pero creo que es menos legible.

+0

No lo sé, me gusta un poco su segundo ejemplo. Nunca he usado el ?? operador, así que estaré interesado en echarle un vistazo. – Kevin

+0

Mi segundo ejemplo también haría una conversión innecesaria de 0 a 'int', que podría o no causarle algunos problemas de rendimiento. No estoy seguro de qué tipo espera de resultsDT, por lo que podría tener que poner un "0" en lugar de solo 0 si está esperando una cadena, etc. –

2

Se puede utilizar un método de conversión de encargo:

public static int ConvertToInt32(object value, int defaultValue) { 
    if (value == null) 
     return defaultValue; 
    return Convert.ToInt32(value); 
} 

Es posible que tenga sobrecargas que toman otros tipos, como cadena. Puede tener problemas con el operador ?? si los tipos de cada lado son diferentes.

+0

Me gusta esta respuesta. Tienes razón, me encontré con un problema usando el ?? operador (recibí el mismo mensaje de error que en mi OP). – Kevin

0

Puede usar el Método de extensión.

int LYSMKWh = resultsDT.Rows[currentRow]["LYSMKWh"].IfNullThenZero(); 

crear la clase por debajo de

public static class Converter 
{ 
    public static Int32 IfNullThenZero(this object value) 
    { 
     if (value == DBNull.Value) 
     { 
      return 0; 
     } 
     else 
     { 
      return Convert.ToInt32(value); 
     } 
    } 
}