0

This problem emerged as a discussion in the comments of this question. Feel free to seek more context if you wish.

Let's say we have the following three variables:

Dim stringArray = {"foo", "bar"}
Dim jaggedArray = {stringArray}
Dim nestedIEnumerable = jaggedArray.Select(Function(arr) arr.Select(Function(s) s))

We can easily concatenate two instances of nestedIEnumerable:

Dim concatenated = nestedIEnumerable.Concat(nestedIEnumerable)

But when trying to call Concat() on the jagged array:

Dim concatenated = jaggedArray.Concat(nestedIEnumerable)

..it does not compile and complains about the following:

'IEnumerable(Of IEnumerable(Of String))' cannot be converted to 'IEnumerable(Of String())' because 'IEnumerable(Of String)' is not derived from 'String()', as required for the 'Out' generic parameter 'T' in 'Interface IEnumerable(Of Out T)'.

Now, this is weird because String()() can be implicitly converted to IEnumerable(Of IEnumerable(Of String)):

Dim casted As IEnumerable(Of IEnumerable(Of String)) = jaggedArray
Dim concatenated = casted.Concat(nestedIEnumerable)

This also works just fine:

Dim concatenated = {stringArray.AsEnumerable}.Concat(nestedIEnumerable)

Why does the first one fail although there's an implicit conversion between the two types?

Note: The C# version of the first code works without a problem:

var stringArray = new[] { "foo", "bar" };
var jaggedArray = new[] { stringArray };
var nestedIEnumerable = jaggedArray.Select((arr) => arr.Select((s) => s));

var concatenated = jaggedArray.Concat(nestedIEnumerable);
dbc
  • 91,441
  • 18
  • 186
  • 284
  • Do you need to materialize the enumerable somehow, e.g. by calling `Count()` or `ToList()`? Or does it fail just on the `Concat` call itself? – dbc May 20 '19 at 02:33
  • 1
    @dbc It fails on the `Concat()` call itself. I wonder if the overload resolution fails to find the appropriate extension method overload in VB but succeeds in C#. I'm not sure what it could be conflicting with though. – 41686d6564 stands w. Palestine May 20 '19 at 02:39
  • The cause isn't the overload resolution but rather the generic type inference. You seem to have the issue backwards, the error is about not being able to implicitly convert *from* an `IEnumerable(Of T)` *to* an array, not the other way around. Don't know enough about VB.NET type inference to say *why* it resolves the type parameter to `String()` rather than `IEnumerable(Of String)` like C# does, though. – kalimag May 20 '19 at 03:25
  • 1
    In the VB.Net implementation `.AsEnumerable()` is not generic. So, `IEnumerable(Of String())` cannot be converted to `IEnumerable(Of IEnumerable(Of String))` – Jimi May 20 '19 at 09:46

0 Answers0