I have some code that takes a value (of type object) and tries to cast it to an IEnumerable of ints and uints like so:
var idList = value as IEnumerable<int>;
var uintList = value as IEnumerable<uint>;
When the value is initialized this way:
uint number = 1;
object value = new []{ number };
both idList and uintList have values, but calling idList.ToList() results in an ArrayTypeMismatchException
. However, when the value is generated with new List<uint>{ number }
, idList is null as expected.
Additionally, calling var idList = value as IEnumerable<int>;
in the immediate window in VS 2015 returns null as I would expect, even when the value was generated with a collection initializer.
.Net fiddle reproducing the error here.
What's going on here?
I think that's because of unusual differences between how C# and CLR treats conversions between int
and uint
, as described in this answer. First note that this code won't compile:
uint[] a1 = new[] { 1u };
var a2 = (int[])a1;
Because C# doesn't believe there exists a cast. However if you go this way:
uint[] a1 = new[] { 1u };
var a2 = (int[]) (object) a1;
Runtime will decide if this cast is valid or not, and it (CLR) thinks differently and allows casting from uint[]
to int[]
(and visa versa), as desribed in answer I linked.
But the same is not true for List<int>
and List<uint>
- they are not treated in a special way by CLR and as such cannot be cast between each other.
So in your case, uint[]
can be cast to int[]
and int[]
implements IEnumerable<int>
, so your idList
is not null. This is not true for Lists - hence your problem.
As for why ToList fails in first case, that's because internally it does something like that:
uint[] a1 = new[] { 1u };
var a2 = (int[]) (object) a1;
// ToList copies contents to new array
int[] copy = new int[a2.Length];
Array.Copy(a2, copy, a2.Length);
And Array.Copy
checks directly if type of elements in one array are compatible with type of elements in another array.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With