I used to think the System.String class was a little confusing -- a reference type which behaves like a value type, by virtue of the simple fact that all of its methods are "const".
Then I peeked under the hood of System.Enum... why? I can't remember. But I'm really confused by what I'm seeing.
The MSDN docs that shipped w/ VS 7.0 state the following: "Enum derives from ValueType, but is not a value type." Hmm... apparently that wasn't unclear enough, so they updated the docs for VS 7.1: "Class Enum is derived from class ValueType; that is, Enum is itself a reference type, not a value type."
Ok, kids -- I enjoy a good joke, but that's too much. What's the real story, here?
I whipped out ILDASM and a managed debugger, and I must say it looks to me like every enum I declare looks and feels just like a valuetype -- with pass by value semantics, the IL "valuetype" keyword, the whole nine yards.
But when I type my code more loosely, with variables and parameters typed as the abstract class System.Enum, I do indeed see pass by reference semantics (eg: the enum argument gets boxed before it's passed to a method). So it seems the docs are correct.
But why? This design decision doesn't make a whole lot of sense to me.
And what does it really mean to have an instance of a System.Enum-derived type? The System.Enum class implements a number of interfaces, but the C# compiler complains when I try to cast a variable of an Enum-derived type to, say, IComparable. (You get no such complaint when casting an ordinary value type, such as a structure.) That seems to be just a compiler hiccup, because ILASM seems to treat enums and structs the same, in this regard.
Hmm... you know, now that I think about it, I guess even System.ValueType is not a really a valuetype, either. This is making my head hurt... but I feel I'm on the verge of an epiphany.