Этот вопрос возникает иногда, но я не нашел удовлетворительного ответа.
Типичный шаблон (строка - DataRow):
 if (row["value"] != DBNull.Value)
 {
      someObject.Member = row["value"];
 }
Мой первый вопрос, который более эффективен (я перевернул условие):
  row["value"] == DBNull.Value; // Or
  row["value"] is DBNull; // Or
  row["value"].GetType() == typeof(DBNull) // Or... any suggestions?
Во-вторых, стоит ли кэшировать значение строки [ "value" ] или компилятор вообще оптимизирует индексатор?
Например:
  object valueHolder;
  if (DBNull.Value == (valueHolder = row["value"])) {}
Примечания:
- строка [ "значение" ] существует.
- Я не знаю индекс столбца столбца (следовательно, поиск имени столбца).
- Я спрашиваю конкретно о проверке DBNull и затем присваивании (не о преждевременной оптимизации и т.д.).
Я сравнил несколько сценариев (время в секундах, 10 000 000 проб):
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 имеет такую же производительность, как "=="
Самый интересный результат? Если вы не учитываете имя столбца в отдельности (например, "Значение" вместо "значение", оно занимает примерно в десять раз дольше (для строки):
row["Value"] == DBNull.Value: 00:00:12.2792374
Мораль этой истории, похоже, состоит в том, что если вы не можете найти столбец по его индексу, убедитесь, что имя столбца, которое вы передаете индектору, точно совпадает с именем DataColumn.
Кэширование значения также кажется почти дважды столь же быстрым:
No Caching: 00:00:03.0996622
With Caching: 00:00:01.5659920
Таким образом, наиболее эффективным методом является:
 object temp;
 string variable;
 if (DBNull.Value != (temp = row["value"]))
 {
      variable = temp.ToString();
 }
