Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3695390
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 19, 20262026-05-19T04:36:43+00:00 2026-05-19T04:36:43+00:00

Edit : Comments at bottom. Also, this . Here’s what’s kind of confusing me.

  • 0

Edit: Comments at bottom. Also, this.


Here’s what’s kind of confusing me. My understanding is that if I have an enum like this…

enum Animal
{
    Dog,
    Cat
}

…what I’ve essentially done is defined a value type called Animal with two defined values, Dog and Cat. This type derives from the reference type System.Enum (something which value types can’t normally do—at least not in C#—but which is permitted in this case), and has a facility for casting back and forth to/from int values.

If the way I just described the enum type above were true, then I would expect the following code to throw an InvalidCastException:

public class Program
{
    public static void Main(string[] args)
    {
        // Box it.
        object animal = Animal.Dog;

        // Unbox it. How are these both successful?
        int i = (int)animal;
        Enum e = (Enum)animal;

        // Prints "0".
        Console.WriteLine(i);

        // Prints "Dog".
        Console.WriteLine(e);
    }
}

Normally, you cannot unbox a value type from System.Object as anything other than its exact type. So how is the above possible? It is as if the Animal type is an int (not just convertible to int) and is an Enum (not just convertible to Enum) at the same time. Is it multiple inheritance? Does System.Enum somehow inherit from System.Int32 (something I would not have expected to be possible)?

Edit: It can’t be either of the above. The following code demonstrates this (I think) conclusively:

object animal = Animal.Dog;

Console.WriteLine(animal is Enum);
Console.WriteLine(animal is int);

The above outputs:

True
False

Both the MSDN documentation on enumerations and the C# specification make use of the term “underlying type”; but I don’t know what this means, nor have I ever heard it used in reference to anything other than enums. What does “underlying type” actually mean?


So, is this yet another case that gets special treatment from the CLR?

My money’s on that being the case… but an answer/explanation would be nice.


Update: Damien_The_Unbeliever provided the reference to truly answer this question. The explanation can be found in Partition II of the CLI specification, in the section on enums:

For binding purposes (e.g., for
locating a method definition from the
method reference used to call it)
enums shall be distinct from their
underlying type. For all other
purposes, including verification and
execution of code, an unboxed enum
freely interconverts with its
underlying type
. Enums can be boxed
to a corresponding boxed instance
type, but this type is not the same
as the boxed type of the underlying
type, so boxing does not lose the
original type of the enum.

Edit (again?!): Wait, actually, I don’t know that I read that right the first time. Maybe it doesn’t 100% explain the specialized unboxing behavior itself (though I’m leaving Damien’s answer as accepted, as it shed a great deal of light on this issue). I will continue looking into this…


Another Edit: Man, then yodaj007’s answer threw me for another loop. Somehow an enum is not exactly the same as an int; yet an int can be assigned to an enum variable with no cast? Buh?

I think this is all ultimately illuminated by Hans’s answer, which is why I’ve accepted it. (Sorry, Damien!)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-19T04:36:44+00:00Added an answer on May 19, 2026 at 4:36 am

    Yes, special treatment. The JIT compiler is keenly aware of the way boxed value types work. Which is in general what makes value types acting a bit schizoid. Boxing involves creating a System.Object value that behaves exactly the same way as a value of a reference type. At that point, value type values no longer behave like values do at runtime. Which makes it possible, for example, to have a virtual method like ToString(). The boxed object has a method table pointer, just like reference types do.

    The JIT compiler knows the method tables pointers for value types like int and bool up front. Boxing and unboxing for them is very efficient, it takes but a handful of machine code instructions. This needed to be efficient back in .NET 1.0 to make it competitive. A very important part of that is the restriction that a value type value can only be unboxed to the same type. This avoids the jitter from having to generate a massive switch statement that invokes the correct conversion code. All it has to do is to check the method table pointer in the object and verify that it is the expected type. And copy the value out of the object directly. Notable perhaps is that this restriction doesn’t exist in VB.NET, its CType() operator does in fact generate code to a helper function that contains this big switch statement.

    The problem with Enum types is that this cannot work. Enums can have a different GetUnderlyingType() type. In other words, the unboxed value has different sizes so simply copying the value out of the boxed object cannot work. Keenly aware, the jitter doesn’t inline the unboxing code anymore, it generates a call to a helper function in the CLR.

    That helper is named JIT_Unbox(), you can find its source code in the SSCLI20 source, clr/src/vm/jithelpers.cpp. You’ll see it dealing with enum types specially. It is permissive, it allows unboxing from one enum type to another. But only if the underlying type is the same, you get an InvalidCastException if that’s not the case.

    Which is also the reason that Enum is declared as a class. Its logical behavior is of a reference type, derived enum types can be cast from one to another. With the above noted restriction on the underlying type compatibility. The values of an enum type have however very much the behavior of a value type value. They have copy semantics and boxing behavior.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Scroll to the bottom, EDIT 19 onwards. See @Chris's comments also for good examples
EDIT: In case you want to test i have deployed the code to this
I have an engine, with this routes file: Rails.application.routes.draw do resources :comments, :controller =>
I have a div that i would like to remove via jquery, but it's
**EDIT: There are several options below that would work. Please vote/comment according to your
EDIT: This post was originally specific to ASP.NET, but after thinking about it I'm
I have a video that I play. To use full screen in iOS 3.2
I'm using MFC for Visual Studio 2003. I have an Edit Control with ID
Does OpenID improve the user experience? Edit Not to detract from the other comments,
I have a Singleton class here designed to be inherited by classes wanting to

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.