2009-07-13 5 views
4

Y a-t-il un moyen de créer mes propres clauses Linq? J'ai étudié les méthodes d'extension et ce n'est pas vraiment ce que je cherche. Je pensais quelque chose comme la clause where, the select ou the from. Je veux utiliser mon code comme telComment créer mes propres clauses Linq?

var blah = from bleep in bloops 
      where bleep == razzie 
      myclause bleep.property 
      select bleep; 

Répondre

4

Vous ne pouvez pas modifier la façon dont le compilateur interprète les instructions de requête. Ces règles sont appelées "compréhensions de requêtes" et les règles de traduction sont directement intégrées dans le compilateur C#. Chaque requête est traduite en une séquence appropriée d'appels dans les méthodes d'extensions dans la bibliothèque Linq.

Si vous utilisez des outils tels que Reflector, vous verrez la séquence correspondante d'appels de méthode d'extension dans lesquels ces expressions sont traduites.

Les règles de compréhension des requêtes sont entièrement documentées dans le C# 3.0 specification. Bien que je convienne qu'il existe des cas spécifiques où il pourrait être utile d'étendre la syntaxe de la requête dans le langage, je suppose qu'il nécessite un traitement de compilation sophistiqué pour les convertir en syntaxe d'appel de fonction appropriée. Je ne pense pas que, dans la plupart des cas, il serait facile d'injecter un traitement pour des cas particuliers sans affecter la façon dont l'expression entière est transformée. En attendant, réalisez que vous pouvez utiliser des méthodes de chaînage et d'extensions régulières pour étendre les capacités de Linq.

2

Pour ce faire, vous devez avoir accès au code source du compilateur C#. Je voudrais rester avec les méthodes d'extension. Si vous avez une copie de Reflector, vous pouvez regarder dans System.Data.Linq et voir comment les méthodes d'extension d'origine ont été écrites.

0

Je ne vois pas pourquoi vous ne pourriez pas utiliser les méthodes d'extension. En utilisant la requête ci-dessus vous le convertirait de ce que vous avez à quelque chose comme ceci:

var blah = (from bleep in bloops 
      where bleep == razzie 
      select bleep).myclause(bleep.property); 
+0

si je voulais faire un type spécial de rejoindre? ou essayez d'imiter différentes fonctionnalités que sql offre qui pourrait être utile contre IQueryable? –

+0

@Russ: Vous pouvez faire tout cela avec des méthodes d'extension, cela ne se traduira pas par une syntaxe de requête. Par exemple: 'var blah = bloops.YourSpecialJoin (blobs) .Where (bip => bip == razzie);' – LukeH

0

Cette syntaxe est juste un peu de sucre autour de ...

var blah = bloops.Where(b => b == razzie); 

Et ce n'est pas extensible ..

Vous pouvez bien sûr ajouter vos propres clauses (juste des méthodes d'extension), vous n'avez tout simplement pas le sucre syntacique.

0

Cela n'est pas possible en C#, mais si vous voulez vraiment ajouter la syntaxe vous-même, vous pouvez écrire un pré-compilateur C# qui inclut les mots-clés supplémentaires de compréhension de requête. Pour l'implémenter de la même manière que C# (comme dans the specification), vous devez rechercher une méthode d'extension MyClause() valide, pour le type de retour de l'objet source ou le type de retour précédent dans la chaîne d'appel, par ex. IEnumerable<T>.

Votre exemple:

var blah = from bleep in bloops 
      where bleep == razzie 
      myclause bleep.property 
      select bleep; 

deviendrait:

var blah = bloops.Where(bleep => bleep==razzie) 
       .MyClause(bleep => bleep.property) 
       .Select(bleep => bleep); 
Questions connexes