在 SqlCommand-ExecuteScalar 错误处理上转换为 int
Cast to int on SqlCommand-ExecuteScalar error handling
我的代码可能很脆弱。此处声明
int countDis = (int)cmd.ExecuteScalar();
如果我将存储过程更改为不 return 任何东西,那么转换为 (int)
将会失败。如果我简单地删除它,那么我就无法编译。
在这种情况下,防御性编码的最佳代码实践是什么?
您可以在投射前检查标量值。
var result = cmd.ExecuteScalar();
int countDis =result != null ? int.Parse(result) : 0;
只需将代码更改为:
int countDis = Convert.ToInt32(cmd.ExecuteScalar());
这将确保即使 ExecuteScalar
returns null
,由于未在存储过程中选择任何内容,countDis
的值也会是 0
.因为Convert.ToInt32(null) = 0
.
更新 (10/12/2018)
更安全的版本。感谢@Moe 强调 DBNull
案例。
object result = cmd.ExecuteScalar();
result = (result == DBNull.Value) ? null : result;
int countDis = Convert.ToInt32(result);
您可以使用 get as Object,并检查其类型然后做出您的决定:
object obj = cmd.ExecuteScalar();
if (obj.GetType() == typeof(string))
{
//you can do your stuff with STRING
}
else if (obj.GetType() == typeof(int))
{
//you can do your stuff with INT
}
else
{
//add here ANYOTHER type you many want in future...
}
我通常使用可空类型。例如:
string str;
int? countDis = cmd.ExecuteScalar() as int?;
if (countDis == null)
str = "count is null";
else
str = "Count is : " + countDis.Value;
这将适用于 ExecuteScalar returns null 或 DBNull.Value。
因为 ExecuteScalar 可以 return DBNull,所以我找到的最好的方法是:
var result = cmd.ExecuteScalar();
int countDis = result != null ? Convert.ToInt32(result) : 0;
如果您将 DBNull.Value
的结果视为与 null
相同的结果,因为它们都应该是 0
,您可以使用单行,尽管您仍在使用一个临时变量。执行速度就不说了:
int countDis = int.TryParse(cmd.ExecuteScalar()?.ToString(), out int temp) ? temp : 0
我的代码可能很脆弱。此处声明
int countDis = (int)cmd.ExecuteScalar();
如果我将存储过程更改为不 return 任何东西,那么转换为 (int)
将会失败。如果我简单地删除它,那么我就无法编译。
在这种情况下,防御性编码的最佳代码实践是什么?
您可以在投射前检查标量值。
var result = cmd.ExecuteScalar();
int countDis =result != null ? int.Parse(result) : 0;
只需将代码更改为:
int countDis = Convert.ToInt32(cmd.ExecuteScalar());
这将确保即使 ExecuteScalar
returns null
,由于未在存储过程中选择任何内容,countDis
的值也会是 0
.因为Convert.ToInt32(null) = 0
.
更新 (10/12/2018)
更安全的版本。感谢@Moe 强调 DBNull
案例。
object result = cmd.ExecuteScalar();
result = (result == DBNull.Value) ? null : result;
int countDis = Convert.ToInt32(result);
您可以使用 get as Object,并检查其类型然后做出您的决定:
object obj = cmd.ExecuteScalar();
if (obj.GetType() == typeof(string))
{
//you can do your stuff with STRING
}
else if (obj.GetType() == typeof(int))
{
//you can do your stuff with INT
}
else
{
//add here ANYOTHER type you many want in future...
}
我通常使用可空类型。例如:
string str;
int? countDis = cmd.ExecuteScalar() as int?;
if (countDis == null)
str = "count is null";
else
str = "Count is : " + countDis.Value;
这将适用于 ExecuteScalar returns null 或 DBNull.Value。
因为 ExecuteScalar 可以 return DBNull,所以我找到的最好的方法是:
var result = cmd.ExecuteScalar();
int countDis = result != null ? Convert.ToInt32(result) : 0;
如果您将 DBNull.Value
的结果视为与 null
相同的结果,因为它们都应该是 0
,您可以使用单行,尽管您仍在使用一个临时变量。执行速度就不说了:
int countDis = int.TryParse(cmd.ExecuteScalar()?.ToString(), out int temp) ? temp : 0