I've found very strange C# compiler behavior for following code:
var p1 = new SqlParameter("@p", Convert.ToInt32(1));
var p2 = new SqlParameter("@p", 1);
Assert.AreEqual(p1.Value, p2.Value); // PASS
var x = 0;
p1 = new SqlParameter("@p", Convert.ToInt32(x));
p2 = new SqlParameter("@p", x);
Assert.AreEqual(p1.Value, p2.Value); // PASS
p1 = new SqlParameter("@p", Convert.ToInt32(0));
p2 = new SqlParameter("@p", 0);
Assert.AreEqual(p1.Value, p2.Value); // FAIL!?
In last line assert fails with following message:
Expected: 0
But was: null
I understand why test fails: p2 = new SqlParameter("@p", 0);
is resolved as SqlParameter(string, SqlDbType)
and for other cases as SqlParameter(string, object)
. But I don't understand why this happens. For me it looks like a bug, but I can't believe that C# compiler could have such kind of bug.
Any reasons for this?
P.S. It seems to be a problem for any method overload with enum parameter and 0 value (SqlDbType is enum).
Basically, the decimal integer literal 0
is implicitly convertible to all enum types (C# 4 spec §6.1.3), so the compiler determines that SqlParameter(string, SqlDbType)
is an applicable function member. Then it has to choose the better between two candidates function members, and it picks SqlParameter(string, SqlDbType)
over SqlParameter(string, object)
, because SqlDbType
is a more specific type than object
(§7.5.3.2).
But I agree that in that case it's very confusing...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With