C# LINQ query on multidimensional array

how would I use the following LINQ query correctly? I want to create a one dimensional array that contains only values that are greater than 5. I can't understand why it can't iterate over this multidimensional array, but if I'll use "foreach" it'd actually iterate.

        // Create an multidimensional array, then just put numbers into it and print the array.  
        int[,] myArr = new int[5,6];
        int rows = myArr.GetLength(0);
        int cols = myArr.GetLength(1);
        for (int i = 0; i < rows; i++)
        {
            for (int k = 0; k < cols; k++)
            {
                myArr[i,k] = i + k;
                Console.Write(myArr[i,k]);
            }
            Console.WriteLine("");

        }
        var highList = from val in myArr where (val > 5) select val;

The error is: Error 1 Could not find an implementation of the query pattern for source type 'int[,]'. 'Where' not found. Are you missing a reference or a using directive for 'System.Linq'?

I thought this might fix the problem:

 public static IEnumerator<int> GetEnumerator(int[,] arr)
    {
     foreach(int i in arr)
     {
         yield return i;
     }
    }

But I guess it doesn't really implement the iterator. I'm sorry if I'm talking weird things here, I'm kind of new to those things... Thank you.

Jon Skeet
people
quotationmark

The problem is that multi-dimensional (rectangular) arrays implement IEnumerable, but not IEnumerable<T>. Fortunately, you can use Cast to fix that - and Cast gets called automatically if you explicitly specify the type of the range variable:

var highList = from int val in myArr where (val > 5) select val;

Or without the unnecessary brackets:

var highList = from int val in myArr where val > 5 select val;

Or using method calls directly, given that it's a pretty trivial query expression:

var highList = myArr.Cast<int>().Where(val => val > 5);

I think this will box each element, however. You could add your own Cast extension method to avoid that:

public static class RectangularArrayExtensions
{
    public static IEnumerable<T> Cast<T>(this T[,] source)
    {
        foreach (T item in source)
        {
            yield return item;
        }
    }
}

people

See more on this question at Stackoverflow