G
Guest
Hopefully someone can set me straight on this issue.
I was testing some code where I have a method that is being overriden. The
method overrides were working fine until I passed a literal 0 (int value) in
as the lone argument.
Well there are two possible overrides that could be called with a single
argument. The first one takes an object and the second one takes an enum
type (SqlTypeCode see the code below). Since a literal 0 is not a
SqlTypeCode I would have expected the override taking an object argument to
be run. However what I found was the override taking the SqlTypeCode was run
instead.
It appears that whenever a literal value that qualifies as a valid enum
value cast to int is used c# will choose to use the SqlTypeCode override
instead of the object. Now whenever a variable of type int is used with a
value that can be cast to the SqlTypeCode value the object override
(expected) is used.
What gives? Is this a bug or am I just misunderstanding something?
If this is not a bug it seems this issue could be something that hides in
the bushes for a long time until it jumps out and bites you.
Thank you,
--
Gregg Walker
Here's the code from a console app...
using System;
using System.Collections.Generic;
using System.Text;
namespace EnumOverrideIssue
{
class Program
{
enum SqlTypeCode
{
Boolean,
Byte,
Char,
DateTime,
Decimal,
Int16,
Int32,
Int64,
Single,
String,
TimeSpan
}
static object myValue = 0;
static SqlTypeCode mySqlType = SqlTypeCode.Int32;
static void Main(string[] args)
{
mySqlType = SqlTypeCode.Int32; string sqlString = ToSqlString();
Console.WriteLine("SqlString=" + sqlString);
// Pass in 0 as literal int
mySqlType = SqlTypeCode.Int32; sqlString = ToSqlString(0);
Console.WriteLine("SqlString=" + sqlString); // Returns 'true' instead of '0'
mySqlType = SqlTypeCode.Int32; sqlString = ToSqlString((int)0);
Console.WriteLine("SqlString=" + sqlString); // Returns 'true' instead of '0'
// Pass in 0 as variable int
myValue = 0; mySqlType = SqlTypeCode.Int32; sqlString =
ToSqlString(myValue); Console.WriteLine("SqlString=" + sqlString); //
Correctly returns '0'
mySqlType = SqlTypeCode.DateTime; sqlString =
ToSqlString(DateTime.Today); Console.WriteLine("SqlString=" + sqlString);
Console.ReadLine();
}
static string ToSqlString()
{
return ToSqlString(myValue, mySqlType);
}
static string ToSqlString(object dataValue)
{
return ToSqlString(dataValue, mySqlType);
}
static string ToSqlString(SqlTypeCode sqlTypeCode)
{
return ToSqlString(myValue, sqlTypeCode);
}
static string ToSqlString(object dataValue, SqlTypeCode sqlTypeCode)
{
switch(sqlTypeCode)
{
case SqlTypeCode.Boolean: return Convert.ToBoolean(dataValue).ToString();
case SqlTypeCode.Byte: return Convert.ToByte(dataValue).ToString();
case SqlTypeCode.Char: return "'" + Convert.ToChar(dataValue).ToString()
+ "'";
case SqlTypeCode.DateTime: return
Convert.ToDateTime(dataValue).ToString();
case SqlTypeCode.Decimal: return Convert.ToDecimal(dataValue).ToString();
case SqlTypeCode.Int16: return Convert.ToInt16(dataValue).ToString();
case SqlTypeCode.Int32: return Convert.ToInt32(dataValue).ToString();
case SqlTypeCode.Int64: return Convert.ToInt64(dataValue).ToString();
case SqlTypeCode.Single: return Convert.ToSingle(dataValue).ToString();
case SqlTypeCode.String: return "'" +
Convert.ToString(dataValue).ToString() + "'";
case SqlTypeCode.TimeSpan: return
TimeSpan.Parse(dataValue.ToString()).ToString();
}
return "NULL";
}
}
}
I was testing some code where I have a method that is being overriden. The
method overrides were working fine until I passed a literal 0 (int value) in
as the lone argument.
Well there are two possible overrides that could be called with a single
argument. The first one takes an object and the second one takes an enum
type (SqlTypeCode see the code below). Since a literal 0 is not a
SqlTypeCode I would have expected the override taking an object argument to
be run. However what I found was the override taking the SqlTypeCode was run
instead.
It appears that whenever a literal value that qualifies as a valid enum
value cast to int is used c# will choose to use the SqlTypeCode override
instead of the object. Now whenever a variable of type int is used with a
value that can be cast to the SqlTypeCode value the object override
(expected) is used.
What gives? Is this a bug or am I just misunderstanding something?
If this is not a bug it seems this issue could be something that hides in
the bushes for a long time until it jumps out and bites you.
Thank you,
--
Gregg Walker
Here's the code from a console app...
using System;
using System.Collections.Generic;
using System.Text;
namespace EnumOverrideIssue
{
class Program
{
enum SqlTypeCode
{
Boolean,
Byte,
Char,
DateTime,
Decimal,
Int16,
Int32,
Int64,
Single,
String,
TimeSpan
}
static object myValue = 0;
static SqlTypeCode mySqlType = SqlTypeCode.Int32;
static void Main(string[] args)
{
mySqlType = SqlTypeCode.Int32; string sqlString = ToSqlString();
Console.WriteLine("SqlString=" + sqlString);
// Pass in 0 as literal int
mySqlType = SqlTypeCode.Int32; sqlString = ToSqlString(0);
Console.WriteLine("SqlString=" + sqlString); // Returns 'true' instead of '0'
mySqlType = SqlTypeCode.Int32; sqlString = ToSqlString((int)0);
Console.WriteLine("SqlString=" + sqlString); // Returns 'true' instead of '0'
// Pass in 0 as variable int
myValue = 0; mySqlType = SqlTypeCode.Int32; sqlString =
ToSqlString(myValue); Console.WriteLine("SqlString=" + sqlString); //
Correctly returns '0'
mySqlType = SqlTypeCode.DateTime; sqlString =
ToSqlString(DateTime.Today); Console.WriteLine("SqlString=" + sqlString);
Console.ReadLine();
}
static string ToSqlString()
{
return ToSqlString(myValue, mySqlType);
}
static string ToSqlString(object dataValue)
{
return ToSqlString(dataValue, mySqlType);
}
static string ToSqlString(SqlTypeCode sqlTypeCode)
{
return ToSqlString(myValue, sqlTypeCode);
}
static string ToSqlString(object dataValue, SqlTypeCode sqlTypeCode)
{
switch(sqlTypeCode)
{
case SqlTypeCode.Boolean: return Convert.ToBoolean(dataValue).ToString();
case SqlTypeCode.Byte: return Convert.ToByte(dataValue).ToString();
case SqlTypeCode.Char: return "'" + Convert.ToChar(dataValue).ToString()
+ "'";
case SqlTypeCode.DateTime: return
Convert.ToDateTime(dataValue).ToString();
case SqlTypeCode.Decimal: return Convert.ToDecimal(dataValue).ToString();
case SqlTypeCode.Int16: return Convert.ToInt16(dataValue).ToString();
case SqlTypeCode.Int32: return Convert.ToInt32(dataValue).ToString();
case SqlTypeCode.Int64: return Convert.ToInt64(dataValue).ToString();
case SqlTypeCode.Single: return Convert.ToSingle(dataValue).ToString();
case SqlTypeCode.String: return "'" +
Convert.ToString(dataValue).ToString() + "'";
case SqlTypeCode.TimeSpan: return
TimeSpan.Parse(dataValue.ToString()).ToString();
}
return "NULL";
}
}
}