2010-06-30 8 views
14

Je veux utiliser LINQ pour interroger un tableau 2D mais je reçois une erreur:LINQ avec tableau 2D, sélectionnez pas trouvé

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

suit:

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

J'ai vérifié que j'ai inclus la référence System.Core et en utilisant System.Linq.

Quelqu'un pourrait-il donner des causes possibles?

+0

De plus, est-ce que this.map implémente IEnumerable/IQueryable? –

+0

@Matthew Abbott: Eh bien, c'est un tableau 2D, donc je suppose que certaines personnes de Microsoft l'ont implémenté. – LLS

+0

duplication possible de [Pourquoi les tableaux multidimensionnels C# n'implémentent-ils pas IEnumerable ?] (Http://stackoverflow.com/questions/275073/why-does-c-multidimensional-arrays-not-implement-ienumerablet) – ChrisF

Répondre

22

pour utiliser votre tableau multidimensionnel avec LINQ, il vous suffit de le convertir en IEnumerable<T>. Il est assez simple, voici deux options par exemple pour l'interrogation

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; 

Chaque syntaxe convertit le tableau 2D en un IEnumerable<T> (parce que vous dites int item dans l'une de clause ou array.Cast<int>() dans l'autre). Vous pouvez ensuite filtrer, sélectionner ou effectuer la projection que vous souhaitez en utilisant les méthodes LINQ.

+1

+1 Beaucoup plus concis que le mien (sauf si vous avez besoin d'un comportement d'énumération personnalisé);) –

+0

Merci. Je pense que je peux utiliser foreach dans un tableau multidimensionnel, et est-ce que C# le convertit aussi en IEnumerable afin que foreach fonctionne? – LLS

+1

@LLS, 'IEnumerable ' n'est pas requis pour la structure de boucle 'foreach'. 'Array' implémente' IEnumerable', et cela correspond à l'exigence. Pour la foreach, la structure doit implémenter/être implicitement convertible en une interface énumérable ('IEnumerable' ou' IEnumerable ') ou avoir les méthodes' GetEnumerator' et 'MoveNext' appropriées. Voir la section 8.8.4 de la spécification de langage C# pour plus de détails. –

11

Votre carte est un tableau multidimensionnel - ceux-ci ne prennent pas en charge les opérations de requête LINQ (voir plus Why do C# Multidimensional arrays not implement IEnumerable<T>?)

Vous devez aplatir le stockage pour votre tableau (probablement la meilleure façon d'aller pour de nombreuses raisons) ou écrire un code d'énumération personnalisé pour elle:

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]; 
    } 
    } 
} 
+0

J'ai seulement vu le retour de rendement dans GetEnumerator, fonctionne-t-il aussi pour retourner un IEnumerable ? – LLS

+0

Bien sûr, essayez-le! –