Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

248
Views
Why does unboxing array to an incorrect type not throw an exception in C#?

There is a weird inconsistency with converting and unboxing values and arrays:

var us = new uint[] { 1, 2, 3 };

var i1 = (int)us[0];                 // direct value to value: works
var i2 = (int)(object)us[0];         // unboxing value to value: compiles, throws at runtime
var is1 = (int[])u;                  // direct array to array: does not compile
var is2 = (int[])(object)u;          // unboxing array to array: works!

is2.GetType().Name                   // UInt32[]

Why is array unboxing allowed, when a direct conversion is prohibited?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Why is array unboxing allowed, when a direct conversion is prohibited?

If you do (int[])(object)us, you are doing two conversions, both of which are allowed by C#:

  • from uint[] to object (you are allowed to cast any reference type to object)
  • from object to int[] (you are allowed to cast from object to any reference type)

Therefore (int[])(object)us compiles.

If you do (int[])us, you are doing a single conversion from int[] to uint[], which is not allowed by C#. According to the C# spec, you can only cast from a T[] to U[] if T and U are reference types, and that you can cast from T to U. int and uint satisfy neither of those, so (int[])us does not compile.

At runtime, the cast from uint[] to int[] is checked to see if it succeeds or fails. The CLR does allow this. See section I.8.7.1 of the CLR spec.

A signature type T is compatible-with a signature type U if and only if at least one of the following holds.

[...]

T is an array with rank r and element type V, and U is an array with the same rank r and element type W, and V is array-element-compatible-with W.

[...]

A signature type T is array-element-compatible-with a signature type U if and only if T has underlying type V and U has underlying type W and either:

  1. V is compatible-with W; or
  2. V and W have the same reduced type.

And the "reduced types" of int and uint are both int.

This is why (int[])(object)us succeeds at runtime.

Also note that casting us to object is not "boxing". Everything is a reference type here. You're just changing the type of the reference.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!