简体   繁体   中英

SqlParameter constructor compiler overload choice

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?

According to the C# Language Specification 4.0 :

the literal 0 implicitly converts to any enum type.


So SqlParameter("parameterName", 0) resolves to the SqlParameter(string, OdbcType) overload.

If you change to SqlParameter("parameterName", 1) it resolves to the SqlParameter(string, object) overload. The same logic applies to Convert.ToInt32 .

0 is the default value of any enum. Hence it is the more exact match than object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM