andrewducker (
andrewducker) wrote2007-05-29 11:48 pm
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Strangeness in C# compilation
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
Fix
The following code works just fine:
Further Reading
For further info see the C# language specification, section 6.1.3
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.
no subject
((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++...
(no subject)
no subject
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)