Converting a <> list to an array - I get "Attempting to access an element as a type incompatible with the array."

I am trying to go through a bunch of elements, each element has an array of List <> objects that I want to convert to an array of arrays. Here is the code for this:

 foreach (IngredientNode i in _snapshot._ingredientMap.Values) { for (int c = 0; c < NUM_TAGS; c++) { if (i.RecipesByTag[c] == null) continue; i.RecipesByTag[c] = i.RecipesByTag[c].ToArray<RecipeNode>(); } <--- EXCEPTION } 

RecipesByTag has the static type IEnumerable<RecipeNode>[] . However, its dynamic type is List<RecipeNode>[] . I want to go through each of them and convert the dynamic type RecopeNode []. Under the debugger, this works, and the i.RecipesByTag is converted. However, the last curly brace throws an exception:

Attempting to access an element as a type incompatible with an array.

I have a feeling that there is some kind of corruption on the stack. Can someone explain what is happening on a technical level here? Thanks!

Mike

+4
source share
2 answers

You do not need to specify a type argument for the ToArray method; it must be inferred from its use if you use strongly typed collections. This is a typical casting problem. You are trying to put elements into an array of some incompatible type.

Your problem should boil to this (these arrays are covariant):

 object[] obj = new string[1]; obj[0] = 5; // compiles fine, yields runtime error 

Now the same thing, with different types (these arrays are also covariant):

 IEnumerable<int>[] x = new List<int>[1]; x[0] = new int[1]; // compiles fine, yields runtime error 

Obviously, why the type system is not like. Basically, you look at it as an IEnumerable<int> array, but it's actually a List<int> array. You cannot put an array of int types into an unrelated array.

I believe Eric Lippert explains this very well on the blog .

+6
source

OK, I think I get what is happening. I have an array of Enumerables. At first it was an array of pointers to a list of objects. Instead, I made it an array of other arrays, in other words, I converted my array to a multidimensional array. Since a multidimensional matrix is โ€‹โ€‹sequential in memory (unlike an array of pointers to other arrays), this completely destroys the array in memory. At least my theory.

What I did completely recreates i.RecipesByTag from scratch. Something like that:

 List<RecipeNode[]> temp = new List<RecipeNode[]>(); for (int c = 0; c < NUM_TAGS; c++) { RecipeNode[] nodes = (i.RecipesByTag[c] == null) ? null : i.RecipesByTag[c].ToArray<RecipeNode>(); temp.Add(nodes); } i.RecipesByTag = temp.ToArray(); 

This works great.

+1
source

All Articles