Reputation: 902
EDIT Summary after solution had been given
*Linq query results are almost always presented with "var" implicit type or with typed IENumerable< T> like IEnumerable< int>. However simple more generic IEnumerable is sufficient
*String.Join() does not have specialization for IEnumerable ( but has naturally one for IEnumerable< T> ) and fall back to String.Join Method (String, Object[] ...). It then assumes that the linq query result res is an array of Object of size 1. I do not know why there is no overload for IEnumerable!
/EDIT
I had imagine that it would be possible to write generic linq query return types. A first idea was to write a code like this:
class exLinq
{
Func<IEnumerable>[] fun_list = new Func<IEnumerable>[]
{ () => { int[] data = { 1, 2, 5, 8, 11 };
var result = from d in data
where 0 == d % 2
select d;
return result;
}
//() => Other queries that could be on string, double... collections
};
static void Main(string args[])
{
foreach (var fun in fun_list)
{
var f = fun;
var res = f();
Console.WriteLine(String.Join(", ",res));
}
}
}
However I got the result
System.Linq.Enumerable+WhereArrayIterator`1[System.Int32]
My linq query return type would be more adequat with IEnumerable < int > ( It works when I do this ) but I was wondering if I could mix in the same array/list queries that would have handle strings,double or whatsoever...
Up to now I got a correct code output with the modification
if ( res is IEnumerable<int>)
Console.WriteLine(String.Join(", ",res.Cast<int>()));
2, 8
More accustomed with C++, I had believed that I would be able to handle any "groups of object" with the "higher" class.
Any idea of how to correctly achieve this?
Upvotes: 1
Views: 572
Reputation: 144206
In this case you can do it if you convert each enumerable to an object[]
before calling string.Join
:
foreach (var fun in fun_list)
{
var f = fun;
var res = f();
Console.WriteLine(String.Join(", ",res.Cast<object>().ToArray()));
}
The reason you're seeing this behaviour is that
string.Join(", ", res);
calls this overload of string.Join
. The params
modifier on the last array parameter allows it to be called with any number of parameters e.g.
string.Join(", ", 1, 2, 3);
Each of these parameters get added to an object[]
which is passed to the method. The Join
method calls ToString
on each element in the array to format it in the output string.
This means that when you call
string.Join(", ", res);
the ToString
method of the generated IEnumerable
is called, which is where "System.Linq.Enumerable+WhereArrayIterator`1[System.Int32]" comes from. You can overcome this behaviour by creating the object[]
yourself and passing it to string.Join
.
You can also use
string.Join(", ", res.Cast<object>());
this resolves to a different overload of string.Join
which calls ToString
on each element of the input sequence.
Upvotes: 1