Bu soru zaman zaman ortaya çıkıyor, ancak tatmin edici bir cevap görmedim.
Tipik bir desen (satır bir DataRow'dur ):
if (row["value"] != DBNull.Value)
{
someObject.Member = row["value"];
}
İlk sorum daha verimli (durumu ters çevirdim):
row["value"] == DBNull.Value; // Or
row["value"] is DBNull; // Or
row["value"].GetType() == typeof(DBNull) // Or... any suggestions?
Bu , .GetType () işlevinin daha hızlı olması gerektiğini gösterir, ancak derleyici bilmediğim birkaç numara biliyordur?
İkinci soru, [[value]] satırının değerini önbelleğe almaya değer mi yoksa derleyici zaten indeksleyiciyi optimize ediyor mu?
Örneğin:
object valueHolder;
if (DBNull.Value == (valueHolder = row["value"])) {}
Notlar:
- satır ["değer"] var.
- Ben sütun (böylece sütun adı arama) sütun dizini bilmiyorum.
- Özellikle DBNull ve sonra atama (erken optimizasyon, vb. Hakkında değil) denetleme hakkında soruyorum.
Birkaç senaryoyu karşılaştırdım (saniye cinsinden süre, 10.000.000 deneme):
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, "==" ile aynı performansa sahip
En ilginç sonuç? Sütun adını duruma göre eşleşmezseniz (örneğin, "değer" yerine "Değer", yaklaşık on kat daha uzun sürer (bir dize için):
row["Value"] == DBNull.Value: 00:00:12.2792374
Hikayenin ahlakı, bir sütunu dizinine göre arayamazsanız, dizinleyiciye beslediğiniz sütun adının DataColumn'un adıyla tam olarak eşleştiğinden emin olunmasıdır.
Değeri önbelleğe almak da neredeyse iki kat daha hızlıdır:
No Caching: 00:00:03.0996622
With Caching: 00:00:01.5659920
Yani en etkili yöntem şöyledir :
object temp;
string variable;
if (DBNull.Value != (temp = row["value"]))
{
variable = temp.ToString();
}
IDataRecord
Uzantıları isterdim .