4

I've got a little code that pulls a boxed ienumerable instance out of an expression tree. The code needs to convert it into object[].

So far I've gotten away with assuming it'll be IEnumerable<string> and thus casting it followed with .ToArray().

Circumstances have changed and now it could also possibly be a IEnumerable<int>. I still need to change the box into an object[] and don't really care what the type is.


object list = Expression.Lambda(methodCallExpression.Object).Compile().DynamicInvoke();

var enumerable = (IEnumerable<string>)list;
object[] values = enumerable.ToArray();

UPDATE:

Strings are references and Integers are value types. I've found that while I can box the reference to an array of ints, I cannot pretend it's an array of boxed ints as int's cannot be boxed.

An exception of type 'System.InvalidCastException' occurred in System.Core.dll but was not handled in user code Additional information: Unable to cast object of type 'System.Collections.Generic.List1[System.Int32]' to type 'System.Collections.Generic.IEnumerable1[System.Object]'.

object list = Expression.Lambda(methodCallExpression.Object).Compile().DynamicInvoke(); 
var enumerable = (IEnumerable<object>)list; 
object[] values = enumerable.ToArray();
Daniel Revell
  • 8,338
  • 14
  • 57
  • 95
  • 3
    Why not relying on `var list` and dealing with this variable without converting it into an array at all? – varocarbas Oct 05 '15 at 13:53
  • "int's cannot be boxed" not sure what you mean - they _can_ be boxed but just casting the collection does not do that _for you_. – D Stanley Oct 05 '15 at 14:14

3 Answers3

5

Just call Cast before ToArray:

object[] values = enumerable.Cast<object>().ToArray();

Note that this casts each item, not the entire collection. You can't "cast" a collection of ints to a collection of objects, you have to convert each item to an object (i.e. box them).

D Stanley
  • 149,601
  • 11
  • 178
  • 240
4

Previously answered in Best way to convert IList or IEnumerable to Array.

Or you could do it the hard way:

  IEnumerable enumberable = (IEnumerable)list;

  List<object> values = new List<object>();

  foreach (object obj in enumerable)
  {
      values.Add(obj);
  }
Community
  • 1
  • 1
  • 1
    I don't think this will work for `IEnumerable`, and definitely won't in C# less than 4.0. `IEnumerable` is covariant from C# 4.0 onwards, but AFAIK, variance doesn't work for value types. It'll work for `IEnumerable` though (on C#>=4.0) – Jcl Oct 05 '15 at 13:55
  • @Jcl I can confirm this doesn't work, I've tested and updated the question as appropriate – Daniel Revell Oct 05 '15 at 14:06
0

Haven't tested it, but you could theoretically cast it to IEnumerable<object> using Linq:

object [] values = ((IEnumerable)list).Cast<object>().ToArray();
Jcl
  • 27,696
  • 5
  • 61
  • 92