octobre
2009
Ne dîtes rien, je vous entends déjà dire : « Oh non, pas encore lui avec son Steve Ballmer qui sera là demain à Paris ! Y en a marre d’entendre la même musique !!!« . Et vous avez raison ! Rassurez-vous, ce n’est pas cette histoire qui va nous empêcher de parler des opérateurs Linq et plus particulièrement des opérateurs Last & LastOrDefault.
Vu que c’est le début de la semaine, je vais faire un petit rappel sur notre fameuse classe MembreDeveloppez qui depuis le temps a continuer d’évoluer :
{
// …
public string Nom { get; set; }
public int NombreMessages { get; set; }
public int CompareTo(MembreDeveloppez other)
{
return this.NombreMessages.CompareTo(other.NombreMessages);
}
}
Vous allez voir que ce nous allons aborder est assez similaire à deux opérateurs que nous avons déjà vu précédemment.
Nous avons toujours une liste d’instances de la classe MembreDeveloppez et dîtes-moi comment vous feriez pour récupérer le dernier élément de cette liste ? En sachant qu’il est y a au moins un élément dans cette liste.
Un Exemple :
Avec l’opérateur Last, vous allez pouvoir obtenir le même résultat :
A la limite un peu moins de lettres à écrire mais on a déjà vu mieux comme évolution. Par contre, comment feriez-vous pour récupérer dans notre liste le dernier membre de Developpez.com qui a écrit au moins 3000 messages ?
Un cas possible :
foreach (var currentMembre in membres)
{
if (currentMembre.NombreMessages >= 3000)
{
membre = currentMembre;
}
}
Console.WriteLine(« {0} est le dernier membre de notre liste qui a écrit au moins 3000 messages. », membre.Nom);
Avec l’opérateur Last, on va pouvoir le faire en une seule ligne de code !
Personnellement, c’est le style d’écriture que j’adore : claire et concise.
Enfin, on va voir une dernière chose car pour rappel, il nous reste encore à illustrer l’utilisation de l’opérateur LastOrDefault. Si on change la contrainte de départ en considérant que notre liste pourrait être vide. Ou bien que la condition ne renvoie aucun résultat. Avec Last, on recevra une exception mais avec LastOrDefault, on récupérera la valeur nulle.
C’est tout pour aujourd’hui !
J’oubliais de vous dire. Dans quelques heures, Steve Ballmer répondra à vos questions lors des Microsoft Days à Paris dès 10h. Et pour ceux qui ne pourront pas être présent à la conférence, l’interview sera retransmise en direct via Live Meeting !
3 Commentaires + Ajouter un commentaire
Déménagement
Next Microsoft CEO
Articles récents
- Changement d’adresse de ce blog
- Article : les nouveautés de C# 5.0
- Modèle Entity Framework généré avec SQL Server 2008 et utilisé sous SQL Server 2005
- Les photos, vidéos et cadeaux des TechDays 2011
- La première journée en ligne sur TechDays TV
- Suivez les TechDays 2011 comme si vous y étiez sur la chaîne TechDays TV
- Téléchargez le programme des conférence des TechDays 2011
- Dernier jour des TechDays = plus de chance de remporter des cadeaux sur le stand de dvp !
- Venez à notre rencontre lors des TechDays 2011
- Les flux à ne pas rater lors des TechDays 2011
- Les TechDays 2011 s’invite sur votre smartphone Windows Phone 7
- Exclu des cadeaux du concours Developpez.com lors des TechDays 2011
- Ouverture de la galerie d’images sur notre site des TechDays
- Partagez votre expérience des Microsoft TechDays
- Grand concours Microsoft “FAN des TechDays 2011” : épisode 2 !
- Mettez-vous aux couleurs des TechDays 2011 !
- Developpez.com aux TechDays 2011
- Le Challenge Azure 2010 est fini !
- Suivez la keynote de la pdc10 en direct sur internet à 18h !
- MVP Visual C# 2010 – 2011 !!!
tu dois avoir raison.
Je suppose que la requete construite au final est la meme, juste sa construction doit être un peu plus rapide
Merci d’avoir cherché
C’est une bonne question et je t’avoue que je ne connais pas la réponse.
Je me suis toujours dit qu’au final, c’est un code fort similaire qui est exécuté. La seule différence est que lors d’un Where().Last(), il y a un accès à deux méthodes statiques différentes alors que dans le cas de Last(), il y a un accès à une seule méthode statique. Donc normalement, c’est Last() avec une lambda qui devrait être légèrement plus rapide.
J’ai d’ailleurs réalisé une test de performance qui semble confirmer ma supposition :
<br />
System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); <br />
<br />
long min1 = long.MaxValue; <br />
long max1 = 0; <br />
List<long> avg1 = new List<long>(); <br />
for (int i = 0; i < 1000000; i++) <br />
{ <br />
watch.Reset(); <br />
watch.Start(); <br />
var result = membres.Where(membre => membre.NombreMessages > 1000).Last(); <br />
watch.Stop(); <br />
<br />
if (min1 > watch.ElapsedTicks) <br />
{ min1 = watch.ElapsedTicks; } <br />
<br />
if (max1 < watch.ElapsedTicks) <br />
{ max1 = watch.ElapsedTicks; } <br />
<br />
avg1.Add(watch.ElapsedTicks); <br />
} <br />
<br />
long min2 = long.MaxValue; <br />
long max2 = 0; <br />
List<long> avg2 = new List<long>(); <br />
for (int i = 0; i < 1000000; i++) <br />
{ <br />
watch.Reset(); <br />
watch.Start(); <br />
var result = membres.Last(membre => membre.NombreMessages > 1000); <br />
watch.Stop(); <br />
<br />
if (min2 > watch.ElapsedTicks) <br />
{ min2 = watch.ElapsedTicks; } <br />
<br />
if (max2 < watch.ElapsedTicks) <br />
{ max2 = watch.ElapsedTicks; } <br />
<br />
avg2.Add(watch.ElapsedTicks); <br />
} <br />
<br />
Console.WriteLine("Methode Where(membre => membre.NombreMessages > 1000).Last()"); <br />
Console.WriteLine("Min {0} Max {1} Avg {2}", min1, max1, avg1.Average()); <br />
Console.WriteLine("Methode Last(membre => membre.NombreMessages > 1000)"); <br />
Console.WriteLine("Min {0} Max {1} Avg {2}", min2, max2, avg2.Average()); <br />
<br />
Console.Read();
Avec comme résultat qui reste dans le même ordre après plusieurs essais :
Methode Where(membre => membre.NombreMessages > 1000).Last()
Min 42 Max 62295 Avg 53,937792
Methode Last(membre => membre.NombreMessages > 1000)
Min 38 Max 27548 Avg 49,761993
vaut-il mieux faire :
SampleLibrary.MembreDeveloppez membre2 = membres.Last(membre => membre.NombreMessages >= 3000);
ou bien
SampleLibrary.MembreDeveloppez membre2 = membres.Where(membre => membre.NombreMessages >= 3000).Last();
?