SqlParameterCollection.Add メソッド には以下のオーバーロードがあります。
-
Add (Object)
-
Add (SqlParameter)
-
Add (String, SqlDbType)
-
Add (String, Object)
-
Add (String, SqlDbType, Int32)
-
Add (String, SqlDbType, Int32, String)
このうち、Add(String, Object) は Add(String, SqlDbType) との曖昧さの問題で廃止され、代わりに AddWithValue メソッド の使用が推奨されています。
何が曖昧かと言うと、MSDN ライブラリの SqlParameterCollection.Add メソッド (String, Object) の説明に書いてありますように、第 2 引数に 0(整数ゼロ)を渡すと、Add (String, Object) ではなくて、Add (String, SqlDbType) オーバーロードが呼び出されることです。
第 2 引数に 0 を渡せばもちろん、(int)0 でも Add (String, SqlDbType) オーバーロードが呼び出されます。
Add (String, Object) オーバーロードを呼び出すには、第 2 引数に Convert.ToInt32(0) または (object)0 を渡さなければなりません。
何故でしょう? 以下のような理由だと思います。(多少推測があります)
まず、SqlDbType が列挙型というところが要注意です。MSDN ライブラリ Enumeration Types (C# Programming Guide) によると、0(整数ゼロ)は列挙型のデフォルト値とのことで、特別な意味を持つようです。
それゆえ、0 や (int)0 は SqlDbType 列挙型のデフォルト値と判断されるらしく、Add (String, Object) ではなくて、Add (string, SqlDbType) オーバーロードが呼ばれます。
Convert.ToInt32(0) は(Object 型から派生した)int 型、(object)0 は Object 型と判断されて、Add (String, Object) オーバーロードが呼ばれます。
ちなみに、もし Add (String, Int32) というオーバーロードがあったとすると、第 2 引数は 0 でも (int)0 でも Convert.ToInt32(0) でも、Add (String, Int32) オーバーロードが呼ばれるはずです。
検証するため以下のサンプルを作ってみましたが、サンプルコード内のコメントにあるように期待通りの結果となりました。
namespace MyConsoleApplication
{
enum Days { Sat, Sun, Mon, Tue, Wed, Thu, Fri };
class TestClass
{
public void Add1(object obj)
{
Console.WriteLine("Add1(object)");
}
public void Add1(Days d)
{
Console.WriteLine("Add1(Days)");
}
public void Add2(object obj)
{
Console.WriteLine("Add2(object)");
}
public void Add2(Days d)
{
Console.WriteLine("Add2(Days)");
}
public void Add2(int i)
{
Console.WriteLine("Add2(int)");
}
}
class Program
{
static void Main(string[] args)
{
TestClass tc = new TestClass();
tc.Add1(0);
tc.Add1(1);
tc.Add1((int)0);
tc.Add1(Convert.ToInt32(0));
tc.Add1((object)0);
Console.WriteLine("--------------------");
tc.Add2(0);
tc.Add2(1);
tc.Add2((int)0);
tc.Add2(Convert.ToInt32(0));
tc.Add2((object)0);
// 結果は:
// Add1(Days)
// Add1(object)
// Add1(Days)
// Add1(object)
// Add1(object)
// --------------------
// Add2(int)
// Add2(int)
// Add2(int)
// Add2(int)
// Add2(object)
}
}
}