C# SqlCommand ExecuteScalar错误处理时强制转换为int
我有可能是脆弱的代码。这句话C# SqlCommand ExecuteScalar错误处理时强制转换为int,c#,sql,sql-server,ado.net,C#,Sql,Sql Server,Ado.net,我有可能是脆弱的代码。这句话 int countDis = (int)cmd.ExecuteScalar(); 如果我将存储过程更改为不返回任何内容,则转换为(int)的操作将失败。如果我只是删除它,那么我就无法编译 在这种情况下,防御编码的最佳代码实践是什么?您可以在强制转换之前检查标量值 var result = cmd.ExecuteScalar(); int countDis =result != null ? int.Parse(result) : 0; 只需将代码更改为: in
int countDis = (int)cmd.ExecuteScalar();
如果我将存储过程更改为不返回任何内容,则转换为(int)
的操作将失败。如果我只是删除它,那么我就无法编译
在这种情况下,防御编码的最佳代码实践是什么?您可以在强制转换之前检查标量值
var result = cmd.ExecuteScalar();
int countDis =result != null ? int.Parse(result) : 0;
只需将代码更改为:
int countDis = Convert.ToInt32(cmd.ExecuteScalar());
这将确保即使ExecuteScalar
返回null
,由于未在存储过程中选择任何内容,countDis
的值也将为0
。因为Convert.ToInt32(null)=0
更新(2018年12月10日)
更安全的版本。感谢@Moe突出显示DBNull
案例
object result = cmd.ExecuteScalar();
result = (result == DBNull.Value) ? null : result;
int countDis = Convert.ToInt32(result);
您可以使用获取作为对象,并检查其类型,然后作出决定:
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...
}
我通常使用可空类型。e、 g:
string str;
int? countDis = cmd.ExecuteScalar() as int?;
if (countDis == null)
str = "count is null";
else
str = "Count is : " + countDis.Value;
这将适用于ExecuteScalar是否返回null或DBNull.Value 因为ExecuteScalar可以返回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
使用likeint?
您可以检查这些:如果您将存储过程更改为不返回任何内容,那么您最好使用cmd.ExecuteNonQuery
,我想。我更改它只是为了测试,它应该总是返回一个计数intSQL Server存储过程不能返回除int
以外的任何东西作为其返回值-所以这真的不是一个问题…敏捷方法学会说您应该只针对当前问题进行编码。这也被称为YAGNI(你不需要它)原则。当然,我个人也不喜欢这一点,但我在这里只是想说明一下@MillRunnerExecuteScalar可以返回DBNull.Value,如果结果集中有一行,但列的值是数据库NULL。在这种情况下,将使用上述代码引发InvalidCastException。如果结果集中没有可从中提取列值的行,ExecuteScalar可以返回null(即C#null)。