andrewducker: (Monkey and Me)
[personal profile] andrewducker
Something I spent a couple of hours digging into today, and caused much strangeness. If you use C# then knowing this might save you having to do the same...

When working out which method to call the compiler works its way up the calling chain from subclass to baseclass looking for a method signature that fits. It stops looking as soon as it finds one. The problem arises because the literal 0 can be mapped onto an enum without any casting. Which means that if there's a subclass with a method on it that takes an enumeration as a parameter and a baseclass with a method that takes an integer the call will be made to the subclass, producing an unexpected result. This is only true with a literal 0 - passing in a variable will work fine.

Sample Code
public enum MyEnum
{
   Zero,
   One,
   Two
}

class MyBaseClass
{
   public string Something (int myInt)
   {
      return ("int" + myInt.ToString());
   }
}

class MySubClass : MyBaseClass
{
   public string Something(MyEnum myEnum)
   {
      return "enum" + ((int)myEnum).ToString();
   }
}

public partial class Form1 : Form
{
   private void button1_Click(object sender, EventArgs e)
   {
      MySubClass x = new MySubClass();
      MessageBox.Show(x.Something(1));
      MessageBox.Show(x.Something(0));
   }
}
This final bit of code will produce "int1" and "enum0".

Fix
The following code works just fine:
private void button1_Click(object sender, EventArgs e)
{
   MySubClass x = new MySubClass();
   int myCounter = 1;
   MessageBox.Show(x.Something(myCounter));
   myCounter = 0;
   MessageBox.Show(x.Something(myCounter));
}

Further Reading
For further info see the C# language specification, section 6.1.3

   C# Language Specification
      6.1.3 Implicit enumeration conversions
      An implicit enumeration conversion permits the decimal-integer-literal 0 to be converted to any enum-type.

Date: 2007-05-30 06:50 am (UTC)
From: [identity profile] call-waiting.livejournal.com
From the description from the spec, it sounds like an explicit cast ((int)0) should do the trick too, as the cast isn't directly an int lit and therefore shouldn't be converted.

That's pretty nasty though. Why only 0? As far as enums are concerned, there really shouldn't be anything special about the value 0. Still, could be worse, could be C++...

Date: 2007-05-30 12:29 pm (UTC)
From: [identity profile] channelpenguin.livejournal.com
hmm, yeah I recall that one. I can't remember the why - I am tantalised by the though tthat I did read an explanation somewhere. maybe I just imagined it...

Date: 2007-05-30 02:27 pm (UTC)
From: [identity profile] martling.livejournal.com
The question is why the additional reading says what it does. It seems like a stupid pointless special case, probably thrown in as a hack to make some other badly designed feature suck less.

Date: 2007-05-31 08:15 am (UTC)
From: [identity profile] channelpenguin.livejournal.com
I meant an explanantion of WHY they did it like that...

Date: 2007-05-31 08:16 am (UTC)
From: [identity profile] channelpenguin.livejournal.com
and yeah it is the flags - memory like a seive.

August 2025

S M T W T F S
      1 2
3 4 5 6 7 8 9
10 11 12 1314 15 16
17 18 19 20 21 22 23
24252627282930
31      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Aug. 23rd, 2025 11:26 am
Powered by Dreamwidth Studios