Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multidimensional arrays do not implement IEnumerable<T>, or do they?

For the reasons that I still do not understand (see this SO question) multidimensional arrays in CLR do not implement IEnumerable<T>. So the following does not compile:

var m = new int[2,2] {{1, 2}, {3, 4}};
var q = from e in m select e;

Then how come that this works just fine in VB.NET?

Sub Main()
    Dim m(,) As Integer = {{1, 2}, {3, 4}}
    Dim q = From e In m Select e

    For Each i In q
        Console.WriteLine(i)
    Next
End Sub

Update:

The following code works because the C# compiler replaces the foreach with for loops to go through each dimension.

foreach(var e in m)
    Console.WriteLine(e);

becomes

int[,] numArray3 = new int[,] { { 2, 2 }, { 3, 3 } };
int upperBound = numArray3.GetUpperBound(0);
int num4 = numArray3.GetUpperBound(1);
for (int i = numArray3.GetLowerBound(0); i <= upperBound; i++)
{
    for (int j = numArray3.GetLowerBound(1); j <= num4; j++)
    {
        int num = numArray3[i, j];
        Console.WriteLine(num);
    }
}
like image 763
Prankster Avatar asked Dec 06 '22 06:12

Prankster


1 Answers

The query works in VB.Net because it gets transformed into

IEnumerable<object> q = m.Cast<object>().Select<object, object>(o => o);

This works because you can call Cast<TResult>() on IEnumerable, which [*,*] implements.

The LINQ query doesn't work in C# because of the different approach the C# and VB.Net designers took. VB.Net takes a more hand holding approach and fixes your mistake and converts IEnumerable to IEnumerable<object> so it can be used.

In C#, you can simulate this by using

var q = from e in m.Cast<object>() select e;
like image 195
Samuel Avatar answered Jan 25 '23 03:01

Samuel