0

How to correctly get String.Join to handle an array when it is referred by object likely with some casting to IEnumerable?

object myArray = new int[]{1,2,3};
Console.WriteLine(String.Join(",", myArray)); // prints System.Int32[]

Particular context:

I have a view in which I receive a list of properties via reflection. These can be single items as well as collections. I wish to print them (the single value or a joined string).

How can I convert a collection to a joined string? I tried (among other things) the following, but this does not work:

@foreach (PropertyInfo cell in Model.GetData().ToList())
{
    <td>
    @{ object value = cell.GetValue(row, null);}
    @(cell.IsCollection() ?
        String.Join(", ", (value as IEnumerable<object>)
            .Select(o => o.ToString()).Select(o => o.ToString())) : value)
    </td>
 }

Info:

  • Cells' type is PropertyInfo.
  • Value is either an object or an object[]. The object or items in the object array can be a string, a boolean or a integer
  • IsCollection is a self written (and tested) extension method which returns true when the PropertyInfo Cell contains a Collection as value

UPDATE: The following does not work either:

if (cell.IsCollection())
{
     values = String.Join(", ", (IEnumerable<object>)value);                              
}

This gives the following error:

Can't convert type System.Collections.Generic.List'1[System.Int32] to type System.Collections.Generic.IEnumerable'1[System.Object].'

Note that:

IEnumerable<object>)value

This works.

String.Join(", ", (IEnumerable<object>)value)

Throws an error of type System.EntryPointNotFoundException

Does anyone know how I can do this correctly?

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
Kai
  • 732
  • 1
  • 7
  • 23

1 Answers1

3

Just simply:

var joinedString = String.Join(", ", value as IEnumerable<object>);

And this:

.Select(o => o.ToString()).Select(o => o.ToString())

is wrong. Because:

// cast to `IEnumerable` of type `object`
(value as IEnumerable<object>)  

// convert to IEnumerable<string>
.Select(o => o.ToString())

// join everything to one string
String.Join(", ", ...)

// and then you again call select on `string`
// which operates on IEnumerable<char>
.Select(o => o.ToString())) 

So as you see, you need to remove these two Select calls.

UPDATE:

Oh, I see. You cannot cast IEnumerable<struct> to IEnumerable<object> due to language restrictions.

LINK

Try this:

// you need to cast to non-generic `IEnumerable`
// then use `Cast` extension method to convert to generic enumerable
IEnumerable<object> valueAsEnumerable = ((IEnumerable)value).Cast<object>();

// then use it in `string.join`
var joinedString = String.Join(", ", valueAsEnumerable);
apocalypse
  • 5,764
  • 9
  • 47
  • 95