2012-10-11 28 views
5

Así que acabo de ver esta línea de código:¿Hay alguna razón para convertir un tipo a su tipo anulable?

Item = (int?)(int)row["Item"]; 

¿Hay una razón por la que no puede simplemente ser:

Item = (int?)row["Item"]; 
+1

Pruébelo y vea (cuando 'row [" Item "]' is 'null', contiene un' int' u otra cosa). – Oded

+0

@Tonnie - Teniendo en cuenta que 'row [" Item "]' contiene un 'object' tratando de convertirlo directamente a un entero que puede contener nulos es una mala idea. –

Respuesta

6

Ver Boxing Nullable Types (C#); un objeto se puede convertir directamente en un int nullable (pero causará una InvalidCastException si el objeto no es realmente un int). Lo único que harán las dos versiones es que una conversión directa a int? no se realizará una comprobación implícita de nulo.

Al convertir a un int y luego a un int nullable, se lanzará un ICE si el valor de la variable de objeto es nulo. Al convertir directamente a un int nullable, null se maneja muy bien, pero se lanzará una excepción InvalidOperationException si el código intenta recuperar la propiedad Value sin verificar que realmente exista uno.

Esto parece un intento a medias para "fallar rápido", y no lo recomendaría como "buen código". Simplemente envíe directamente a las anotaciones, y luego pruebe la propiedad HasValue e inicie desde allí.

0
Item = (int?)(int)row["Item"]; 

esta línea lanza una excepción en el caso row["Item"] es nulo. Esta mala idea, no lo hagas.

0

Puede utilizar la palabra clave as.

Item = row["Item"] as int?; 
+0

Esto puede causar una InvalidCastException si el objeto contenido en 'row [" Item "]' no es un entero. Además, no usaría ninguno de los métodos, ya que ninguno de los dos resolvería muchos problemas heredados con el lanzamiento de este tipo. –

+3

@Ramhound: el operador 'as' devuelve' null' si el objeto no es un entero. –

+0

Entonces, aquí está la GRAN pregunta, ¿cuáles son las ventajas de '(int?) Row [" Item "]' over 'row [" Item "] como int?'? –

3

Creo que la manera correcta de escribir esta línea de código es la siguiente:

int val; 
var success = int.TryParse(Convert.ToString(row["Item"]), out val); 
Item = success ? (int?)val : (int?)null; 
0

Puede efectivamente emitidos null como el tipo anulable

Item = sdr.IsDBNull(sdr.GetOrdinal("Item")) ? (int?)null : (int)row["Item"]; 

No es muy seguro qué excepciones esta puede causar, pero lo he usado sin problema.

Cuestiones relacionadas