Syntaxe des méthodes d’extension vs syntaxe de requête

J’essaie de savoir si le moment est venu d’utiliser des mots-clés linq standard ou des méthodes d’extension linq avec des expressions lambda. Ils semblent faire la même chose, sont simplement écrits différemment. Est-ce uniquement une question de style?

var query = from p in Products where p.Name.Contains("foo") orderby c.Name select p; // or with extension methods: var query = Products .Where(p => p.Name.Contains("foo")) .OrderBy(p => p.Name); 

Ils sont très similaires, le deuxième exemple étant un peu plus concis, mais peut-être moins expressif si vous ne savez pas ce que fait le =>.

Outre l’écriture du code laconique, y at-il d’autres avantages à utiliser les méthodes d’extension que la syntaxe LINQ?

Honnêtement, il peut parfois arriver que vous utilisiez les fonctions et les actions. Disons que vous utilisez ces trois funcs:

  Func userName = user => user.UserName; Func userIDOverTen = user => user.UserID < 10; Func userIDUnderTen = user => user.UserID > 10; 

Comme vous pouvez le voir, le premier remplace l’expression lamdba pour obtenir le nom d’utilisateur, le second remplace une expression lamdba utilisée pour vérifier si l’ID est inférieur à 10 et avouons-le, le troisième devrait être assez facile à comprendre maintenant.

NOTE: Ceci est un exemple idiot mais ça marche.

  var userList = from user in userList where userIDOverTen(user) select userName; 

Contre

  var otherList = userList .Where(IDIsBelowNumber) .Select(userName) 

Dans cet exemple, le second est un peu moins verbeux puisque la méthode d’extension peut utiliser pleinement le Func, mais l’expression Linq ne peut pas, car il s’agit uniquement d’un booléen plutôt que d’un Func qui retourne un booléen. Cependant, il est préférable d’utiliser le langage d’expression. Disons que vous avez déjà une méthode qui ne se limite pas à un utilisateur:

  private Boolean IDIsBelowNumber(DataClasses.User user, Int32 someNumber, Boolean doSomething) { return user.UserID < someNumber; } 

Note: doQuelque chose est juste là à cause de la méthode d'extension où ok est une méthode qui prend un utilisateur et un entier et retourne un booléen. Un peu ennuyeux pour cet exemple.

Maintenant, si vous regardez la requête Linq:

  var completeList = from user in userList where IDIsBelowNumber(user, 10, true) select userName; 

Tu es bon pour ça. Maintenant, la méthode d'extension:

  var otherList = userList .Where(IDIsBelowNumber????) .Select(userName) 

Sans une expression lambda, je ne peux vraiment pas appeler cette méthode. Alors maintenant, ce que je dois faire, c'est créer une méthode qui crée un Func basé sur l'appel de méthode d'origine.

  private Func IDIsBelowNumberFunc(Int32 number) { return user => IDIsBelowNumber(user, number, true); } 

Et puis twigz-le:

  var otherList = userList .Where(IDIsBelowNumberFunc(10)) .Select(userName) 

Ainsi, vous pouvez voir que parfois, il est parfois plus simple d’utiliser l’approche par requête.

L’un des avantages de l’utilisation des méthodes d’extension LINQ ( requêtes basées sur des méthodes) est que vous pouvez définir des méthodes d’extension personnalisées et qu’elles sont toujours lisibles.

En revanche, lors de l’utilisation d’une expression de requête LINQ, la méthode d’extension personnalisée ne figure pas dans la liste des mots clés. Il semblera un peu étrange mélangé avec les autres mots-clés.

Exemple

J’utilise une méthode d’extension personnalisée appelée Into qui ne prend qu’une chaîne:

Exemple avec une requête

 var query = (from p in Products where p.Name.Contains("foo") orderby c.Name select p).Into("MyTable"); 

Exemple avec des méthodes d’extension

 var query = Products .Where(p => p.Name.Contains("foo")) .OrderBy(p => p.Name) .Into("MyTable"); 

À mon avis, cette dernière, utilisant une requête basée sur une méthode , lit mieux lorsque vous avez des méthodes d’extension personnalisées.

Je pense que c’est une bonne idée de ne pas les utiliser ensemble et d’en choisir un et de s’y tenir.

La plupart du temps, ce sont des goûts personnels, mais dans la syntaxe de requête (méthode de compréhension), tous les opérateurs ne sont pas disponibles, comme cela a été dit précédemment.

Je trouve la syntaxe des méthodes d’extension plus conforme au rest de mon code. Je fais mon SQL en SQL. Il est également très facile de construire votre expression en ajoutant simplement les méthodes d’extension.

Juste mes deux cents.

Comme je ne peux pas encore faire de commentaires, je veux en faire une réponse à l’outil de programmation: pourquoi faire une toute nouvelle méthode pour le dernier exemple? Tu ne peux pas juste utiliser:

.Where(user => IDIsBelowNumber(user, 10, true))

Ils comstacknt les mêmes et sont équivalents. Personnellement, je préfère les méthodes lambda (extension) pour la plupart des choses, en utilisant uniquement les instructions (standard) si je fais LINQ to SQL ou si j’essaie d’imiter SQL. Je trouve que les méthodes lambda s’écoulent mieux avec le code, alors que les instructions sont visuellement distrayantes.

Je préfère la syntaxe de la méthode d’extension lorsque j’utilise les méthodes Linq qui n’ont pas d’équivalent de syntaxe de requête, telles que FirstOrDefault () ou autres.

J’aime utiliser la syntaxe de requête lorsque c’est vraiment une requête, c’est-à-dire une expression paresseuse qui évalue à la demande.

Une méthode qui ressemble à des appels de méthode réguliers (syntaxe de méthode ou syntaxe lambda) ne semble pas assez paresseuse, donc je l’utilise comme une convention. Par exemple,

 var query = from p in Products where p.Name.Contains("foo") orderby p.Name select p; var result = query.ToList(); //extension method syntax 

Si ce n’est pas une requête, j’aime le style courant qui me semble compatible avec d’autres appels exécutés avec impatience.

 var nonQuery = Products.Where(p => p.Name.Contains("foo")) .OrderBy(p => p.Name) .ToList(); 

Cela m’aide à mieux différencier les deux styles d’appels. Bien sûr, il y a des situations où vous serez obligé d’utiliser la syntaxe de la méthode de toute façon, donc ma convention n’est pas assez convaincante.

L’un des avantages des méthodes d’extension / expressions lynda réside dans les opérateurs supplémentaires proposés, tels que Skip and Take. Par exemple, si vous créez une méthode de pagination, il est facile de pouvoir ignorer les 10 premiers enregistrements et passer aux 10 prochains enregistrements.