tschmit007
tschmit007

Reputation: 7800

why as IEnumerable is not enumerated by string.Join

given the following running method:

internal static void DefaultShow(object o) {
    if ( o is IEnumerable) {
        StringBuilder sb = new StringBuilder(1024);
        foreach(var i in o as IEnumerable ) {
            sb.Append($"{i}|");
        }
        Console.WriteLine(sb.ToString());
    } else {
        Console.WriteLine(o.ToString());
    }
}

DefaultShow("a,b,c".Split(","));

displays:

"a|b|c|"

when:

internal static void DefaultShow(object o) {
    if ( o is IEnumerable) {
        Console.WriteLine(string.Join("|", o as IEnumerable));
    } else {
        Console.WriteLine(o.ToString());
    }
}

DefaultShow("a,b,c".Split(","));

displays:

System.String[]

Upvotes: 1

Views: 631

Answers (5)

StepUp
StepUp

Reputation: 38134

It happens because you are joining as IEnumerable. So to show the all items you should cast to IEnumerable<string>:

if (o is IEnumerable<string>)
{             
    Console.WriteLine(string.Join("|", (o as IEnumerable<string>)));             
}
else
{
     Console.WriteLine(o.ToString());
}

Upvotes: 0

Viktor Arsanov
Viktor Arsanov

Reputation: 1593

Check which method is used

enter image description here

The (o as IEnumerable) is treated as an item of object array(because of params), while the method you need expectes IEnumerable<string>.

Update: Btw, I don't know why the Visual Studio shows me that the first argument has char type - it should be string, seems to be an issue with VS))

Upvotes: 0

Sweeper
Sweeper

Reputation: 271830

If you look at the list of overloads of string.Join, none of them accept an IEnumerable. There's one that accepts an IEnumerable<string>, but that's it.

Therefore, your call to string.Join will bind to the overload that takes a params object[]. From the perspective of the method, the object[] has only one element, and that is the IEnumerable, so it calls ToString() on that and returns.

You probably want to cast the IEnumerable to an IEnumerable<object> first, then convert everything to a string by ToString:

internal static void DefaultShow(object o) {
    if ( o is IEnumerable) {
        Console.WriteLine(string.Join("|", (o as IEnumerable).Cast<object>().Select(x => x.ToString())));
    } else {
        Console.WriteLine(o.ToString());
    }
}

Upvotes: 4

Skaria Thomas
Skaria Thomas

Reputation: 419

Console.WriteLine(o) will call o.ToString() internally and that will display System.String[] because variable o is a string array.

Upvotes: 0

apocalypse
apocalypse

Reputation: 5884

Because string.Join("|", o as IEnumerable) will use this overload:

public static string Join(string separator, params object[] values)

There is no overload which takes IEnumerable as a parameter. There is overload only for generic version (IEnumerable<T>).

Upvotes: 0

Related Questions