enum bug in clr?

  • Thread starter Thread starter Thomas Hansen
  • Start date Start date
T

Thomas Hansen

Hi!

I fell in a pit today while coding.. calling OverLoadedMethod (see
below) with anything but literal 0 calls the object overload, but with
0 the enum overload is automagically called. No warnings, no errors.

The Framework class System.Data.SqldClietn.SqlParameter behaves this
way... you can create SqlParameter using an object value and that
works great if the value is not literal 0.. then it decides the 0
matches the enum and you get something quite different than what you
expected..

By design or flaw?


using System;

class App
{
public enum SomeKindOfEnum
{
Should,Red,Flag,ComeUp,Now
}

static void Main(string[] args)
{
int varZero = 0;
int varOne = 1;
OverloadedMethod( varZero );
OverloadedMethod( varOne );
OverloadedMethod( 0 );
OverloadedMethod( 1 );
}

static void OverloadedMethod( object a)
{
// This is the one I want to call.
}

static void OverloadedMethod( SomeKindOfEnum a)
{
Console.WriteLine("Bummer!");
}
}
 
Thomas Hansen said:
I fell in a pit today while coding.. calling OverLoadedMethod (see
below) with anything but literal 0 calls the object overload, but with
0 the enum overload is automagically called. No warnings, no errors.

The Framework class System.Data.SqldClietn.SqlParameter behaves this
way... you can create SqlParameter using an object value and that
works great if the value is not literal 0.. then it decides the 0
matches the enum and you get something quite different than what you
expected..

By design or flaw?

Well, it's certainly not a bug in the compiler. From section 13.1.3 of
the language spec:

"An implicit enumeration conversion permits the decimal-integer-literal
0 to be converted to any enum-type."

and when choosing which overload to use, section 14.4.2.3 is invoked,
including:

<quote>
# 5 If an implicit conversion from T1 to T2 exists, and no implicit
conversion from T2 to T1 exists, C1 is the better conversion.
# 6 If an implicit conversion from T2 to T1 exists, and no implicit
conversion from T1 to T2 exists, C2 is the better conversion.
</quote>

In our case, C1 is the conversion from the decimal-integer-literal 0 to
the enumeration (T1), and C2 is the conversion from the
decimal-integer-literal 0 to object (T2).

Now, because there is an implicit conversion from the enumeration to
object, but not from object to the enumeration, C1 is the better
conversion - which is why the overload with the enumeration is called.

In the other cases, there's no implicit conversion from int to the
enumeration, so it's never an issue.
 
Well, it's certainly not a bug in the compiler. From section 13.1.3 of
the language spec:

"An implicit enumeration conversion permits the decimal-integer-literal
0 to be converted to any enum-type."

Thanks for the help! I was not aware of that. I still don't
understand why they'd put this rule there but.
 
My question, would boxing the zero solve the problem?

-----Original Message-----
Well, it's certainly not a bug in the compiler. From
section 13.1.3 of the language spec:

"An implicit enumeration conversion permits the decimal-
integer-literal 0 to be converted to any enum-type."

and when choosing which overload to use, section 14.4.2.3
is invoked, including:

<quote>
# 5 If an implicit conversion from T1 to T2 exists, and
no implicit conversion from T2 to T1 exists, C1 is the
better conversion.
# 6 If an implicit conversion from T2 to T1 exists, and no
implicit conversion from T1 to T2 exists, C2 is the better
conversion.
</quote>

In our case, C1 is the conversion from the decimal-integer-
literal 0 to the enumeration (T1), and C2 is the
conversion from the decimal-integer-literal 0 to object
(T2).

Now, because there is an implicit conversion from the
enumeration to object, but not from object to the
enumeration, C1 is the better conversion - which is why
the overload with the enumeration is called.

In the other cases, there's no implicit conversion from
int to the enumeration, so it's never an issue.
 
Back
Top