When creating an SqlParameter
(.NET3.5) or OdbcParameter
, I often use the SqlParameter(string parameterName, Object value)
constructor overload to set the value in one statement.
However, when I tried passing a literal 0 as the value parameter, I was initially caught by the C# compiler choosing the (string, OdbcType)
overload instead of (string, Object)
.
MSDN actually warns about this gotcha in the remarks section, but the explanation confuses me.
Why does the C# compiler decide that a literal 0 parameter should be converted to OdbcType
rather than Object
? The warning also says to use Convert.ToInt32(0)
to force the Object
overload to be used.
It confusingly says that this converts the 0 to an "Object type". But isn't 0 already an "Object type"? The Types of Literal Values section of this page seems to say literals are always typed and so inherit from System.Object
.
This behavior doesn't seem very intuitive. Is this something to do with Contra-variance or Co-variance maybe?
0 is the default value of any enum. Hence it is the more exact match than object.
According to the C# Language Specification 4.0:
So
SqlParameter("parameterName", 0)
resolves to theSqlParameter(string, OdbcType)
overload.If you change to
SqlParameter("parameterName", 1)
it resolves to theSqlParameter(string, object)
overload. The same logic applies toConvert.ToInt32
.