34

I want to use Linq to query a 2D array but I get an error:

Could not find an implementation of the query pattern for source type 'SimpleGame.ILandscape[,]'. 'Select' not found. Are you missing a reference to 'System.Core.dll' or a using directive for 'System.Linq'?

Code is following:

var doors = from landscape in this.map select landscape;

I've checked that I included the reference System.Core and using System.Linq.

Could anyone give some possible causes?

4

2 Answers 2

47

In order to use your multidimensional array with LINQ, you simply need to convert it to IEnumerable<T>. It's simple enough, here are two example options for querying

int[,] array = { { 1, 2 }, { 3, 4 } };

var query = from int item in array
            where item % 2 == 0
            select item;

var query2 = from item in array.Cast<int>()
                where item % 2 == 0
                select item;

Each syntax will convert the 2D array into an IEnumerable<T> (because you say int item in one from clause or array.Cast<int>() in the other). You can then filter, select, or perform whatever projection you wish using LINQ methods.

Sign up to request clarification or add additional context in comments.

3 Comments

+1 Much more concise than mine (unless you need custom enumeration behavior) ;)
Thanks. I think I can use foreach in multidimensional array, and does C# also convert it to IEnumerable<T> in order to make foreach work?
@LLS, IEnumerable<T> is not required for the foreach looping structure. Array implements IEnumerable, and this fits the requirement. For the foreach, the structure needs to implement/be implicitly convertible to an enumerable interface (IEnumerable or IEnumerable<T>) or have appropriate GetEnumerator and MoveNext methods. See section 8.8.4 of the C# language specification for more details.
22

Your map is a multidimensional array--these do not support LINQ query operations (see more Why do C# Multidimensional arrays not implement IEnumerable<T>?)

You'll need to either flatten the storage for your array (probably the best way to go for many reasons) or write some custom enumeration code for it:

public IEnumerable<T> Flatten<T>(T[,] map) {
  for (int row = 0; row < map.GetLength(0); row++) {
    for (int col = 0; col < map.GetLength(1); col++) {
      yield return map[row,col];
    }
  }
}

1 Comment

I only saw yield return in GetEnumerator, does it also work to return an IEnumerable<T>?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.