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 8238093
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 7, 20262026-06-07T19:41:38+00:00 2026-06-07T19:41:38+00:00

Normally, one would expect, and hope, that two casts are needed to first unbox

  • 0

Normally, one would expect, and hope, that two casts are needed to first unbox a value type and then perform some kind of value type conversion into another value type. Here’s an example where this holds:

  // create boxed int
  IFormattable box = 42;       // box.GetType() == typeof(int)


  // unbox and narrow
  short x1 = (short)box;       // fails runtime :-)
  short x2 = (short)(int)box;  // OK

  // unbox and make unsigned
  uint y1 = (uint)box;         // fails runtime :-)
  uint y2 = (uint)(int)box;    // OK

  // unbox and widen
  long z1 = (long)box;         // fails runtime :-)
  long z2 = (long)(int)box;    // OK (cast to long could be made implicit)

As you can see from my smileys, I’m happy that these conversions will fail if I use only one cast. After all, it’s probably a coding mistake to try to unbox a value type into a different value type in one operation.

(There’s nothing special with the IFormattable interface; you could also use the object class if you prefer.)

However, today I realized that this is different with enums (when (and only when) the enums have the same underlying type). Here’s an example:

  // create boxed DayOfWeek
  IFormattable box = DayOfWeek.Monday;    // box.GetType() == typeof(DayOfWeek)


  // unbox and convert to other
  // enum type in one cast
  DateTimeKind dtk = (DateTimeKind)box;   // succeeds runtime :-(

  Console.WriteLine(box);  // writes Monday
  Console.WriteLine(dtk);  // writes Utc

I think this behavior is unfortunate. It should really be compulsory to say (DateTimeKind)(DayOfWeek)box. Reading the C# specification, I see no justification of this difference between numeric conversions and enum conversions. It feels like the type safety is lost in this situation.

Do you think this is “unspecified behavior” that could be improved (without spec changes) in a future .NET version? It would be a breaking change.

Also, if the supplier of either of the enum types (either DayOfWeek or DateTimeKind in my example) decides to change the underlying type of one of the enum types from int to something else (could be long, short, …), then all of a sudden the above one-cast code would stop working, which seems silly.

Of course, the enums DayOfWeek and DateTimeKind are not special. These could be any enum types, including user-defined ones.

Somewhat related: Why does unboxing enums yield odd results? (unboxes an int directly into an enum)

ADDITION:

OK, so many answers and comments have focused on how enums are treated “under the hood”. While this is interesting in itself, I want to concentrate more on whether the observed behavior is covered by the C# specification.

Suppose I wrote the type:

struct YellowInteger
{
  public readonly int Value;

  public YellowInteger(int value)
  {
    Value = value;
  }

  // Clearly a yellow integer is completely different
  // from an integer without any particular color,
  // so it is important that this conversion is
  // explicit
  public static explicit operator int(YellowInteger yi)
  {
    return yi.Value;
  }
}

and then said:

object box = new YellowInteger(1);
int x = (int)box;

then, does the C# spec say anything about whether this will succeed at runtime? For all I care, .NET might treat a YellowInteger as just an Int32 with different type metadata (or whatever it’s called), but can anyone guarantee that .NET does not “confuse” a YellowInteger and an Int32 when unboxing? So where in the C# spec can I see if (int)box will succeed (calling my explicit operator method)?

  • 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-06-07T19:41:39+00:00Added an answer on June 7, 2026 at 7:41 pm

    When you use:

    IFormattable box = 42; 
    long z2 = (long)(int)box;
    

    You are actually unboxing and then casting.

    But in your second case:

    IFormattable box = DayOfWeek.Monday; 
    DateTimeKind dtk = (DateTimeKind)box;
    

    You don’t perform any casting at all. You just unbox the value. The default underlying type of the enumeration elements is int.

    Update to refer to the real question:

    The specification you mentioned in the comment:

    The explicit enumeration conversions are:
    ...
    From any enum-type to any other enum-type.
    

    This is actually correct. We cannot implicitly convert:

    //doesn't compile
    DateTimeKind dtk = DayOfWeek.Monday;
    

    But we can explicitly convert:

    DateTimeKind dtk = (DateTimeKind)DayOfWeek.Monday;
    

    It seems that you found a case when this is still required. But when combined with unboxing, only explicit conversion needs to be specified and unboxing can be ommited.

    Update 2

    Got a feeling that somebody must have noticed that before, went to Google, searched for “unboxing conversion enum” and guess what? Skeet blogged about it in 2005 (CLI spec mistake with unboxing and enums)

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

Sidebar

Related Questions

Normally I would have one junit test that shows up in my integration server
I have this code that where I would normally use one line: if (tableView
Say I have two models and one belongs to another. Now normaly you would
Normally, in Delphi one would declare a function with a variable number of arguments
Normally one would declare/allocate a struct on the stack with: STRUCTTYPE varname; What does
In Haskell, in order to represent the literal string \ , one would normally
Will there normally only be one instance of MainForm? I need to hold it
Normally I'm pretty competent with CSS but I just can't figure this one out...
A bytecode program is normally executed by parsing the instructions one at a time.
I have a byte[] member in one of my persistable classes. Normally, I'd just

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.