7

I have a method that returns a List<string> and I'm trying to pass that to the AddRange(Object[]) method of a ComboBox.

How can I convert my List<string> to Object[]?

I suppose I could do a foreach but I'd rather use the AddRange(Object[]) as it's faster (and produces less code).

EDIT

The following works fine:

var list = new List<string>();
object[] array = list.ToArray<object>();
comboBox.AddRange(array);

However, on another note, any reason why I would want to perform the above instead of:

var list = new list<string>();
comboBox.AddRange(list.ToArray<object>());
cogumel0
  • 2,430
  • 5
  • 29
  • 45

6 Answers6

15

You can do it using ToArray generic method:

var list = new List<string>();
object[] array = list.ToArray<object>();

You don't even need Cast<object>, because ToArray takes IEnumerable<T> which is covariant on generic type parameter.

MarcinJuraszek
  • 124,003
  • 15
  • 196
  • 263
  • 2
    Arrays are also covariant, so you don't even need to do `list.ToArray()`, you can just to `list.ToArray()`. – Magnus Grindal Bakken Sep 05 '13 at 10:21
  • 2
    @MagnusGrindalBakken: Well, it depends on whether the OP may want to store non-strings in the same array later. – Jon Skeet Sep 05 '13 at 10:23
  • @MagnusGrindalBakken You can take advantage of that, when calling methods like `AddRange`, but otherwise when you'd like to use that array later I would suggest using `ToArray` instead of array covariance. – MarcinJuraszek Sep 05 '13 at 10:24
  • 2
    @MagnusGrindalBakken just doing `list.ToArray()` produces a warning saying `Co-variant array conversion from string[] to object[] can cause run-time exception on write operation`. – cogumel0 Sep 05 '13 at 10:26
  • @cogumel0 The warning you're quoting is the same Jon Skeet pointed few comments above. – MarcinJuraszek Sep 05 '13 at 10:27
  • @cogumel0 I think that's a Resharper warning. (I don't use Resharper so I've never seen it.) It's certainly a good idea to steer clear of array covariance in general, although it shouldn't be an issue in this case if all you're doing is `comboBox.Items.AddRange(myList.ToArray());`. I won't discourage you from working around the warning. – Magnus Grindal Bakken Sep 05 '13 at 10:35
4

You can use something like to be explicit about the change of the type:

object[] array = yourList.Cast<Object>().ToArray();

or simply be implicit:

yourcomboBox.AddRange(yourList.ToArray());
sloth
  • 99,095
  • 21
  • 171
  • 219
1
List<string> items = ...;
cb.Items.AddRange(items.ToArray());
FireShock
  • 1,082
  • 1
  • 15
  • 25
  • The only solution here that doesn't forget that arrays are covariant already in C#. – Sebastian Redl Sep 05 '13 at 10:21
  • 1
    This produces `Co-variant array conversion from string[] to object[] can cause run-time exception on write operation`, which is why I deviated from it. – cogumel0 Sep 05 '13 at 10:23
1

Maybe this works:

object[] myArray = myList.OfType<object>().ToArray();
BendEg
  • 20,098
  • 17
  • 57
  • 131
0

Arrays of references are covariant (slowly covariant) with arrays of their base classes (and with arrays of their interfaces, and with other arrays), so you can:

AddRange(mystrings.ToArray());

mystrings.ToArray() is a string[], that is covariant with an object[] (so that the AddRange will accept it)

From 12.5 Array covariance

For any two reference-types A and B, if an implicit reference conversion (Section 6.1.4) or explicit reference conversion (Section 6.2.3) exists from A to B, then the same reference conversion also exists from the array type A[R] to the array type B[R]

xanatos
  • 109,618
  • 12
  • 197
  • 280
0

If it's about convenience:

public static class ObjectCollectionExtension
{
    public static void AddAll<T>(this ComboBox.ObjectCollection self, IEnumerable<T> es)
    {
        foreach (var e in es)
            self.Add(e);
    }
}

Might have gotten the generics wrong, I'm a bit rusty.

Sebastian Redl
  • 69,373
  • 8
  • 123
  • 157