这个问题偶尔会出现,但我没有看到一个令人满意的答案。
典型的模式是(row 是 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?
这个 表明. GetType ()应该更快,但是也许编译器知道一些我不知道的技巧?
第二个问题,是否值得缓存 row [“ value”]的值,或者编译器是否优化了索引器?
例如:
object valueHolder;
if (DBNull.Value == (valueHolder = row["value"])) {}
备注:
我对一些场景(以秒为单位的时间,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
ReferenceEquals 的性能与“ = =”相同
最有趣的结果是什么?如果按大小写不匹配列的名称(例如,“ Value”而不是“ Value”,大约需要10倍的时间(对于字符串) :
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();
}