壊れやすいコードがあります。このステートメントはこちら
int countDis = (int)cmd.ExecuteScalar();
ストアドプロシージャを変更して何も返さないようにすると、そのキャストは(int)
が爆発します。単に削除すると、コンパイルできません。
この状況での防御的コーディングの最良のコードプラクティスは何ですか?
次のようにコードを変更してください:
_int countDis = Convert.ToInt32(cmd.ExecuteScalar());
_
これにより、ストアドプロシージャで何も選択しなかった結果としてExecuteScalar
がnull
を返した場合でも、countDis
の値は_0
_になります。なぜならConvert.ToInt32(null) = 0
だからです。
更新(2018年12月12日)
安全なバージョン。 DBNull
ケースを強調してくれて@Moeに感謝します。
_object result = cmd.ExecuteScalar();
result = (result == DBNull.Value) ? null : result;
int countDis = Convert.ToInt32(result);
_
キャストする前にスカラー値を確認できます。
var result = cmd.ExecuteScalar();
int countDis =result != null ? int.Parse(result) : 0;
通常、null許容型を使用します。例えば:
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を返すかどうかに関係なく機能します。
_DBNull.Value
_の結果をnull
と同じように扱うと、どちらも_0
_になるはずですが、一時変数を使用しているにもかかわらず、1行を使用できます。実行速度については触れません。
int countDis = int.TryParse(cmd.ExecuteScalar()?.ToString(), out int temp) ? temp : 0
ExecuteScalarはDBNullを返すことができるため、私が見つけた最良の方法は次のとおりです。
var result = cmd.ExecuteScalar();
int countDis = result != null ? Convert.ToInt32(result) : 0;
を使用して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...
}