34 votes

Quand dois-je utiliser LINQ pour C #?

J'apprends le C # et je trouve LINQ absolument intéressant. Cependant, ce qui me laisse perplexe, je ne peux pas imaginer un scénario dans lequel l'utilisation de LINQ serait une immense aide, car ce n'est vraiment pas si difficile de répliquer les fonctionnalités de LINQ dans le code.

Avez-vous des expériences / suggestions personnelles à partager?

Merci!

19voto

tvanfosson Points 268301

Je trouve que je suis en utilisant LINQ juste au sujet de tout le temps que je l'ai déjà écrit une boucle pour remplir un conteneur. J'ai utiliser LINQ to SQL comme mon ORM et beaucoup de LINQ partout ailleurs.

Voici un petit extrait de code que j'ai écrit pour un Active Directory de la classe helper qui permet de déterminer si un utilisateur est un un groupe particulier. Remarque l'utilisation de Tout() pour itérer sur l'autorisation de l'utilisateur groupes jusqu'à en trouver un avec un SID correspondant. Beaucoup plus propre que le code de l'alternative.

private bool IsInGroup( GroupPrincipal group, UserPrincipal user )
{
    if (group == null || group.Sid == null)
    {
        return false;
    }
    return user.GetAuthorizationGroups()
               .Any( g => g.Sid != null && g.Sid.CompareTo( group.Sid ) == 0 );
}

Alternative:

private bool IsInGroup( GroupPrincipal group, UserPrincipal user )
{
    if (group == null || group.Sid == null)
    {
        return false;
    }
    bool inGroup = false;
    foreach (var g in user.GetAuthorizationGroups())
    {
         if ( g => g.Sid != null && g.Sid.CompareTo( group.Sid ) == 0 )
         {
            inGroup = true;
            break;
         }
    }
    return inGroup;
}

ou

private bool IsInGroup( GroupPrincipal group, UserPrincipal user )
{
    if (group == null || group.Sid == null)
    {
        return false;
    }

    foreach (var g in user.GetAuthorizationGroups())
    {
         if ( g => g.Sid != null && g.Sid.CompareTo( group.Sid ) == 0 )
         {
            return true;
         }
    }
    return false;
}

Voici un extrait de code qui fait une recherche par rapport à un référentiel, des commandes, et convertit les 10 premiers d'affaires assorti d'objets dans un modèle spécifique à la vue (Distance est Levenshtein distance d'édition de la correspondance du modèle id unique à partir de l'id unique paramètre).

model.Results = this.Repository.FindGuestByUniqueID( uniqueID, withExpired )
                               .OrderBy( g => g.Distance )
                               .Take( 10 )
                               .ToList()
                               .Select( g => new GuestGridModel( g ) );

16voto

Joel Coehoorn Points 190579

Cela dépend de quel type de linq que tu veux dire.

Est-il linq-to-sql? Dans ce cas, c'est un orm avec tous les avantages qui viennent de l'utilisation de tout autre orm. Je ne l'utilise pas beaucoup et ne peut pas vraiment en dire plus.

Est-il linq-to-objets? Dans ce cas, vous êtes vraiment parler d'une collection d'autres choses: les méthodes d'extension, paresseux itérateurs, et une requête de compréhension de la syntaxe. C'est une introduction dans le monde de la programmation fonctionnelle. Je n'ai pas beaucoup d'utilisation pour la requête compréhension de la syntaxe, mais pour le reste, je peux le démontrer par un exemple.

Disons que vous voulez lire un fichier ligne par ligne. Pour chaque ligne, vous voulez vérifier si elle répond à certains critères, de convertir une partie de ces lignes à un entier, et la somme des 10 premiers de ces entiers qui sont également dans une certaine plage. Voici le vieux chemin, vous pourriez faire cela:

int SumXValues(string filename)
{
    string line;
    int sum = 0;
    int count = 0;
    using (var rdr = new StreamReader(filename))
    {

        while ( (line = rdr.ReadLine()) != null && count < 10)
        {
           int val;
           if (int.TryParse(line.Substring(3,3))
           {
               if (val > 4 && val < 25)
               {
                    sum += val;
                    count ++;
               }
            }
        }
    }
    return sum;
}

Voici la nouvelle façon:

IEnumerable<string> ReadLines(string filename)
{
    string line;
    using (var rdr = new StreamReader(filename))
        while ( (line = rdr.ReadLine()) != null)
           yield return line;
}

int SumXValues(string filename)
{
    return ReadLines(filename)
               .Select(l => l.Substring(3,3))
               .Where(l => int.TryParse(l))
               .Select(i => int.Parse(i))
               .Where(i => i > 4 && i < 16)
               .Take(10)
               .Sum(i => i);
}

Notez le nouveau code est en fait plus courte. Mais pourquoi est-il aussi de mieux? Il y a (au moins) 4 raisons:

  • J'espère que c'est évident de savoir comment re-utilisable de la readlines fonction. Vous pourriez facteur plus que bien, mais le point est de montrer comment ce style vous aide à la ré-utilisation du code plus.
  • Il évolue mieux. De l'avis de tous l'enchaînement des appels de fonction dans cette dernière fonction. Vous savez combien de fois que le code s'itérateur sur les lignes dans votre fichier? Exactement une fois! En fait, même pas longtemps, il va arrêter de lire à partir du fichier après la prise de la première 10 articles. Et si vous changez le retour d'une énumération, puis l'utiliser ailleurs avec d'autres méthodes d'extension? Encore juste une fois! Cela vous permet de construire, mélanger, et re-mélangez les résultats de votre requête à l'exécution sans coûteuse des passages supplémentaires sur vos listes.
  • C'est plus facile à gérer. Si les changements de critères, il est facile de repérer les l'exacte "règle" (si vous voulez) que vous vous souciez et de modifier simplement la partie.
  • C'est plus lisible. Cela permet d'exprimer le code en fonction de ce qu'il est en train de faire, plutôt que de la façon dont il le fait.

12voto

Je trouve LINQ utile lorsque j'ai une collection d'un certain objet, et je suis intéressé par des articles qui répondent à certains critères. Exemple Simple serait de rechercher toutes les formes dans une collection de formes, qui sont des cercles.

var circles =
        from s in allShapes
        where s.Type == ShapeTypes.Circle
        select s;

J'avoue que je pourrais avoir juste d'écrire une boucle avec un peu de code, mais j'ai trouver ce code plus court et plus facile à écrire, et plus facile à lire et à comprendre.

LINQ peut également être utilisé avec les bases de données, mais je trouve que je ne fais pas grand-chose. À chacun son/sa propre, je suppose.

10voto

Taylor Leese Points 18895

Le livre Essentiel de LINQ fournit un excellent résumé d'un paragraphe de la prestation de LINQ:

LINQ n'est plus que de simplement ajouter de nouveaux les caractéristiques de la langue. Il introduit une delcarative style de la programmation dans le langage C#. L' modèle de programmation déclarative permet les développeurs de l'artisanat code succictly capte leur intention, sans le forcer à s'inquiéter l'ordre dans lequel les événements ont lieu, ou leur mise en application précise. Il permet aux développeurs d'état de ce qu'ils voulez faire, plutôt que la façon dont il sera fait.

7voto

David Hedlund Points 66192

Vous avez raison, c'est rarement très difficile à reproduire les fonctionnalités régulièrement en C#. C'est ce qu'ils appellent sucre syntaxique. C'est juste une question de commodité. Vous savez automatique propriétés? Celles qui vous permettent d'écrire public class User { public int Id { get; set; } } C'est extrêmement facile à reproduire dans la "régulière" de code C#. De même, automatique propriétés sont encore génial ;)

De filtrage et de tri sont à peu près la base de LINQ. Envisagez-vous une liste des utilisateurs, appelé, ainsi, users, et que vous voulez trouver ceux qui ont connecté d'aujourd'hui, et de les afficher dans l'ordre le plus récemment connecté. Avant de LINQ, vous auriez probablement faire quelque chose comme créer une nouvelle liste, que vous remplissez basé sur l'original de la liste, par itération, en ajoutant ce que répond aux critères, et ensuite, mettre en place une sorte de IComparable. Maintenant, vous pouvez simplement faire:

users = users.Where(u => u.LastLoggedIn.Date = DateTime.Today)
             .OrderBy(u => u.LastLoggedIn).ToList();

Commodité =)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X