¿La forma más eficiente de verificar DBNull y luego asignar a una variable?

Esta pregunta surge ocasionalmente, pero no he visto una respuesta satisfactoria.

Un patrón típico es (la fila es unDataRow):

 if (row["value"] != DBNull.Value)
 {
      someObject.Member = row["value"];
 }

Mi primera pregunta es cuál es más eficiente (he cambiado la condición):

  row["value"] == DBNull.Value; // Or
  row["value"] is DBNull; // Or
  row["value"].GetType() == typeof(DBNull) // Or... any suggestions?

Esta indica que .GetType () debería ser más rápido, pero ¿tal vez el compilador conoce algunos trucos que yo no?

Segunda pregunta, ¿vale la pena almacenar en caché el valor de la fila ["valor"] o el compilador optimiza el indexador de todos modos?

Por ejemplo:

  object valueHolder;
  if (DBNull.Value == (valueHolder = row["value"])) {}

Notas:

la fila ["valor"] existe.No sé el índice de columna de la columna (de ahí la búsqueda del nombre de la columna).Estoy preguntando específicamente sobre la comprobación de DBNull y luego la asignación (no sobre la optimización prematura, etc.).

Comparé algunos escenarios (tiempo en segundos, 10,000,000 pruebas):

row["value"] == DBNull.Value: 00:00:01.5478995
row["value"] is DBNull: 00:00:01.6306578
row["value"].GetType() == typeof(DBNull): 00:00:02.0138757

Object.ReferenceEquals tiene el mismo rendimiento que "=="

¿El resultado más interesante? Si no coincide el nombre de la columna por mayúsculas y minúsculas (por ejemplo, "Valor" en lugar de "valor", se tarda aproximadamente diez veces más (para una cadena):

row["Value"] == DBNull.Value: 00:00:12.2792374

La moraleja de la historia parece ser que si no puede buscar una columna por su índice, asegúrese de que el nombre de la columna que alimenta al indexador coincida exactamente con el nombre de la columna de datos.

El almacenamiento en caché del valor también parece ser casidos veces tan rápido:

No Caching: 00:00:03.0996622
With Caching: 00:00:01.5659920

Entonces, el método más eficienteparece ser:

 object temp;
 string variable;
 if (DBNull.Value != (temp = row["value"]))
 {
      variable = temp.ToString();
 }

Respuestas a la pregunta(15)

Su respuesta a la pregunta