Câu hỏi này thỉnh thoảng xuất hiện, nhưng tôi chưa thấy câu trả lời thỏa đáng.
Một mẫu điển hình là (hàng là DataRow ):
if (row["value"] != DBNull.Value)
{
someObject.Member = row["value"];
}
Câu hỏi đầu tiên của tôi là cái nào hiệu quả hơn (tôi đã lật điều kiện):
row["value"] == DBNull.Value; // Or
row["value"] is DBNull; // Or
row["value"].GetType() == typeof(DBNull) // Or... any suggestions?
Điều này chỉ ra rằng .GetType () sẽ nhanh hơn, nhưng có lẽ trình biên dịch biết một vài thủ thuật mà tôi không biết?
Câu hỏi thứ hai, có đáng lưu vào bộ đệm giá trị của hàng ["value"] hay trình biên dịch có tối ưu hóa trình chỉ mục không?
Ví dụ:
object valueHolder;
if (DBNull.Value == (valueHolder = row["value"])) {}
Ghi chú:
- hàng ["giá trị"] tồn tại.
- Tôi không biết chỉ số cột của cột (do đó tra cứu tên cột).
- Tôi đang hỏi cụ thể về việc kiểm tra DBNull và sau đó chỉ định (không phải về tối ưu hóa sớm, v.v.).
Tôi đã điểm chuẩn một vài kịch bản (thời gian tính bằng giây, 10.000.000 thử nghiệm):
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 có hiệu suất tương tự như "=="
Kết quả thú vị nhất? Nếu bạn không khớp tên của cột theo trường hợp (ví dụ: "Giá trị" thay vì "giá trị", sẽ mất khoảng mười lần lâu hơn (đối với một chuỗi):
row["Value"] == DBNull.Value: 00:00:12.2792374
Đạo đức của câu chuyện dường như là nếu bạn không thể tra cứu một cột theo chỉ mục của nó, thì hãy đảm bảo rằng tên cột bạn cung cấp cho người lập chỉ mục khớp chính xác với tên của DataColumn.
Bộ nhớ đệm giá trị cũng xuất hiện nhanh gần gấp đôi :
No Caching: 00:00:03.0996622
With Caching: 00:00:01.5659920
Vì vậy, phương pháp hiệu quả nhất dường như là:
object temp;
string variable;
if (DBNull.Value != (temp = row["value"]))
{
variable = temp.ToString();
}
IDataRecord
phần mở rộng yêu thích .