A maneira mais eficiente de verificar o DBNull e depois atribuir a uma variável?

Esta pergunta surge ocasionalmente, mas não vi uma resposta satisfatória.

Um padrão típico é (linha é umDataRow):

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

Minha primeira pergunta é qual é mais eficiente (eu inverti a condição):

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

este indica que .GetType () deve ser mais rápido, mas talvez o compilador conheça alguns truques que eu não conheço?

Segunda pergunta, vale a pena armazenar em cache o valor da linha ["value"] ou o compilador otimiza o indexador de qualquer maneira?

Por exemplo:

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

Notas:

a linha ["valor"] existe.Não conheço o índice da coluna (daí a pesquisa do nome da coluna).Estou perguntando especificamente sobre a verificação de DBNull e depois a atribuição (não sobre otimização prematura etc.).

Comparei alguns cenários (tempo em segundos, 10.000.000 de tentativas):

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 tem o mesmo desempenho que "=="

O resultado mais interessante? Se você não combinar o nome da coluna por caso (por exemplo, "Valor" em vez de "valor", levará aproximadamente dez vezes mais (para uma sequência):

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

A moral da história parece ser que, se você não puder procurar uma coluna por seu índice, verifique se o nome da coluna que você alimenta no indexador corresponde exatamente ao nome da DataColumn.

O armazenamento em cache do valor também parece ser quaseduas vezes tão rápido:

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

Então, o método mais eficienteparece ser estar:

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

questionAnswers(15)

yourAnswerToTheQuestion