Dot.Blog

C#, XAML, Xamarin, UWP/Android/iOS

Linq au quotidien, petites astuces et utilisations détournées...

Linq je vous en parle souvent, c'est tellement génial. Et ce que j'aime bien c'est trouver des utilisations presque à contre-sens de Linq.
J'entends par là des façons de "rentabiliser" Linq à toute autre tâche que d'interroger des données (SQL, XML ou autres).

Je ne suis pas le seul dans ce cas ! J'ai au moins trouvé un autre zigoto qui s'amuse au même jeu, Igor Ostrovsky dont vous pouvez visiter le blog (cliquez sur son nom). Comme il s'exprime en anglais et que je sais que certains visiteurs ici ne sont pas forcément doués pour cette langue, voici une adaptation libre(*) de son billet présentant quelques astuces très amusantes.
(*) je n'ai repris que les exemples de code, le texte et le projet exemple sont de mon cru, si vous parlez anglais je vous laisse découvrir la prose de Igor sur son blog.

Initialiser un tableau, une liste

Il est souvent nécessaire d'initialiser une array avec des éléments qui, pour que cela soit utile, répondent à certains critères. Normalement cela se règle soit sous la forme d'une liste de constantes dans la déclaration de l'array, ce qui est pour le moins assez peu souple, soit sous la forme d'un code d'initialisation, ce qui du coup devient assez lourd pour parfois pas grand chose... C'est oublier que Linq peut apporter ici une aide non négligeable !

Voici trois exemples :

int[] A = Enumerable.Repeat(-1, 10).ToArray();
int[] B = Enumerable.Range(0, 10).ToArray();
int[] C = Enumerable.Range(0, 10).Select(i => 100 + 10 * i).ToArray();

Les trois arrays contiendront 10 éléments. "A" contiendra 10 éléments tous égaux à -1. "B" contiendra la suite 0 à 9, et "C" contiendra la suite de 100 à 190 par pas de 10.

Amusant, n'est-il pas ?

Plusieurs itérations en une seule

Imaginons que nous possédions deux arrays, A1 et B2, chacune contenant une sélection différente d'éléments. Supposons que souhaitions appliquer le traitement "Calcule(x)" aux éléments de ces deux arrays. La solution s'imposant serait :

foreach (var x in A1) { Calcule(x); }
foreach (var x in A2) { Calcule(x); }

Ce n'est pas très long, mais répéter du code n'est jamais très élégant. Voici comme Linq permet de faire la même chose en une seule boucle :

foreach (var x in A1.Concat(A2)) { Calcule(x); }

L'opérateur Concat effectue une .. concaténation, donnant l'illusion à notre boucle qu'elle travaille sur une seule et même array alors qu'il n'en est rien... On notera que Linq travaillant au niveau des énumérateurs, il n'y même pas de variable temporaire créée par le mécanisme pour stocker la concaténation. C'est élégant et en plus c'est efficace du point de vue de la mémoire.

Fun, isn't it ?

Créer des séquences aléatoires

Il est parfois nécessaire de créer des séquences aléatoires, pour tester un bout de code par exemple. La classe Random est bien pratique mais encore une fois il faudra déclarer le tableau puis déclarer une méthode pour l'initialiser en utilisant Random. Avec Linq tout cela peut se réduire à deux déclarations :

Random rand = new Random();
var ListeAléatoire = Enumerable.Repeat(0, 10).Select(x => rand.Next(10,500));

Le tableau "ListeAléatoire" contiendra 10 nombres aléatoires entre 10 et 500, et pas une seule déclaration de méthode à l'horizon. Vous noterez en revanche l'utilisation qui est faite de l'expression Lambda (nouveauté de C# 3.0) au niveau du Select.

Créer des chaînes de caractères

Si les exemples portent jusqu'ici sur des tableaux de nombres, c'est par pure souci de simplification. Il est bien entendu possible d'appliquer les mêmes astuces à d'autres types de données comme les chaînes :

 string chaine = new string( Enumerable.Range(0, 20) .Select(i => (char)(‘A’ + i % 3)) .ToArray());

La chaîne "chaine" contiendra "ABCABCABCABCABCABCAB". Remplacez le "20" par un "rand.Next(10,100)" par exemple, et en plus la longueur de la chaîne sera elle-même aléatoire. C'est pas pratique ça ?

Dans les commentaires du blog de Igor, un lecteur proposait une autre façon d'initialiser une chaîne avec Linq, la voici pour l'intérêt de la démonstration de la versatilité de Linq :

string chaine2 = string.Join(string.Empty, Enumerable.Repeat("ABC", 7).ToArray());

Ici on peut passer une pattern et un nombre de répétition.

Convertir une valeur en séquence de 1 objet

Il est parfois nécessaire de convertir une valeur en une séquence de longueur 1. Passer un paramètre unique là où un tableau de valeur est attendu réclame de créer le fameux tableau et de l'initialiser. Rien de bien méchant mais pourquoi ne pas mettre Linq à contribution ?

IEnumerable<int> sequence = Enumerable.Repeat(LaValeur, 1);

La répétition de 1 élément peut sembler être une sorte de contresens, mais si les concepteurs de la fonction partageaient cette opinion n'auraient-ils pas levé une exception pour toute valeur inférieure à 2 ... :-)
C'est en tout cas un moyen bien pratique d'arriver au résultat souhaité en une seule opération !

Enumérer tous les sous-ensembles d'un tableau

Il s'agit plus ici d'un "plaisir pervers" que d'une réelle utilité quotidienne il faut l'avouer, mais pour l'intérêt de la syntaxe voici comment énumer tous les sous ensembles d'un tableau (attention, si la taille du tableau dépasse quelques dizaines d'éléments le temps de calcul peut vite exploser ...) :

T[] tableau = …;
var subsets = from m in Enumerable.Range(0, 1 << tableau.Length)
              select
                  from
i in Enumerable.Range(0, tableau.Length)
                  where (m & (1 << i)) != 0
                  select arr[i];

Je vous laisse réfléchir à la syntaxe, peu évidente de prime abord, et le côté un peu "tordu" de cette astuce, mais elle répond à un besoin qui l'est tout autant. Et Linq peut aussi servir à cela.
Quelques clés pour comprendre : la requête ne retourne pas des items de "tableau" mais bien des sous ensembles de "tableau", c'est à dire des tableaux. Chaque tableau contient une combinaison unique d'éléments de "tableau". Si vous prenez tableau = B de notre premier exemple (c'est à dire la suite d'entiers 0 à 9), la requete Linq ci-dessus retournera 1024 sous-ensembles. Avouez que bien qu'un peu difficile à comprendre à première lecture, le procédé est d'une grande élégance... (Vous pouvez regarder le fonctionnement de cette requête de plus près grâce au projet démo téléchargeable en fin d'article).

Un peu de code...

Pour mieux comprendre les choses il est toujours préférable de faire tourner un bout de code. J'y ai pensé ! Vous trouverez un projet console complet plus bas ;-)

Conclusion

Igor montre au travers de ces différentes utilisations de Linq ce que je tente aussi de vous montrer dans mes billets : Linq est d'une grande souplesse, Linq ne se limite pas à faire du SQL en C#, Linq est un atout majeur pour le développeur qui sait s'en servir au quotidien. Initialiser un tableau, convertir un tableau dans un type différent, jouer sur les combinatoires, fabriquer des chaînes de caractères ou des séquences aléatoires de test, etc, etc. Il n'y a pas un bout de code dans lequel il ne soit possible de glisser un peu de Linq pour le rendre plus sobre, plus élégant et souvent plus performant.
Remercions Igor pour ces exemples de code (seule chose reprise de son billet, j'ai mon propre style, il a le sien :-) )

Le code complet

LinqFun.rar (99,18 kb)

Bonus 

Mitsu, qu'on ne présente plus, ça serait faire insulte à sa notoriété !, a proposé il y a quelques temps déjà une autre astuce Linq tout à fait amusante, elle consiste à obtenir la décomposition d'un nombre en facteurs premiers au travers de requêtes Linq et d'un class helper permettant d'écrire : 144.ToPrimeNumbersProduct() et d'obtenir en sortie "2^3 * 3^2 * 7". Je vous en conseille la lecture en suivant ce lien.

 

Régler le problème de cast dans les visualiseurs de debug personnalisés sous VS 2008

L'infamant message "Unable to cast object of type votreClasseDeVisualiseur to type Microsoft.VisualStudio.DebuggerVisualizers.DialogDebuggerVisualizer" vous saute à la figure lorsque vous cliquez sur la petite loupe d'une propriété en mode debug ?

Vous êtes sous VS 2008 ? Alors il y a toutes les chances que le problème soit inversement aussi simple que le nombre d'heures que vous avez passé à chercher pourquoi sans trouver !

En effet, les premières versions de VS 2008 avait un petit problème dans le template de création des visualiseurs, et le problème arrive donc aussi avec les visualiseurs que vous avez repris de VS 2005. C'est tout bête, regardez dans les Références du projet de visualiseur, et cliquez sur Microsoft.VisualStudio.DebuggerVisualizers, et regardez les propriétés... Version est très certainement à 8.0.0.0, donc VS 2005. Il suffit de supprimer la référence puis de l'ajouter en choisissant cette fois-ci la même DLL (dans la page .NET d'ajout de référence) mais dans sa version 9.0.0.0.

C'est tout ! il n'y a plus qu'à redéployer le visualiseur dans le répertoire C:\Program Files\Microsoft Visual Studio 9.0\Common7\Packages\Debugger\Visualizers (installation par défaut en tout cas) et Hop ! Vous n'êtes même pas obligé de fermer VS 2008, normalement la nouvelle DLL sera détectée automatiquement.

 Merci qui ?  :-)

 Stay Tuned !

 

PS : pour ceux qui ne savent pas de quoi je parle, juste un mot, car c'est vraiment bête d'ignorer ça...
Les visualiseurs de debug sont des ajouts que vous pouvez "plugger" dans VS pour visualiser (en debug donc) le contenu d'une classe particulière. VS est livré avec quelques visualiseurs, c'est pour ça qu'en debug pour certaines propriétés, lorsque vous passez la souris dessus (après avoir placé un point d'arrêt généralement) vous pouvez voir une petite loupe. En cliquant dessus vous accédez à un afficheur spécialisé, plus pratique que le défilement de toutes les propriétés (comportement par défaut). De fait si vous débuggez une appli qui possèdent ses propres classes un peu complexes, il est très vite rentable d'écrire des visualiseurs qui permettent de gagner beaucoup de temps en debug... Renseignez-vous, des tutors existent sur le Web, et c'est très simple à mettre en oeuvre.

Mieux utiliser les "Master Page" de ASP.NET

Quelle belle invention que les pages maîtres (Master Page) introduites sous ASP.NET 2.0 ! Quand on pense aux contorsions nécessaires pour avoir un menu ou des bandeaux lattéraux sans cet ajout décisif, et pire quand on sait comment il fallait faire ( et qu'il faut encore faire) sous d'autres environnements...

Bref les pages maître c'est super. Mais voilà, il arrive que les pages de contenu doivent accéder à des champs de la page maître, soit pour y lire certaines informations, soit pour en écrire (cas d'un label d'info se trouvant sur une MP dont le contenu est changé par la page courante par exemple).

La (mauvaise) méthode habituelle 

Prenons l'exemple du label (que vous remplacerez mentalement par ce que vous voulez du moment qu'il s'agit d'un objet de la MP). On rencontre très souvent un code qui ressemble à cela dans les pages détails :

Label info = this.Master.Page.FindControl("labelInfo") as Label;
if (info != null) { info.Text = "information sur la page en cours..."; }

 Et encore, le test sur le null est plutôt un luxe qui ne se voit pas dans tous les codes !

Bien entendu cette méthode fonctionne, mais elle n'est franchement pas propre. Au moins pour une raison, c'est qu'une simple erreur de frappe dans le FindControl et c'est le bug, pas trop grave si le test sur null est ajouté comme dans l'exemple de code ci-dessus, mais bug quand même. En aucun cas le compilateur ne peut détecter l'erreur. Dommage pour un environnement fortement typé !

Mais ne riez pas trop vite, on rencontre des horreurs bien pire que le code montré ici : certains n'hésitent pas à transtyper la propriété this.Master.Page pour accéder directement à l'objet ! Et comme un mauvais chemin ne peut mener qu'à faire des âneries de plus en plus grosses, les éléments d'interface étant protected par défaut, pour que ça passe (en force!) les mêmes sont donc contraints de modifier la visibilité de l'objet convoité en le faisant passer en public. Dire que c'est du bricolage est très largement en dessous de la réalité.

Heureusement il existe une solution très simple qui marche et qui permet d'écrire un code de bien meilleur qualité, c'est la directive MasterType, trop peu connue et encore moins utilisée (il y a même des pervers qui en ont entendu parlé mais qui ne s'en servent pas, si, ça existe!).

La (bonne) méthode à utiliser

Elle se décompose en deux temps :

  • Temps 1 : Créer des propriétés dans la page maître
  • Temps 2 : utiliser la directive MasterType

La propriété 

Continuons sur notre exemple du label, il conviendra alors d'écrire quelque chose du genre (dans le code de la page maître donc) :

 public Label InfoLabel { get { return labelInfo; } }

Honnêtement il y a encore mieux à faire, personnellement je n'aime pas voir des objets exposés de la sorte. On créera plutôt une propriété de ce type :

public string Info { get { return labelInfo.Text; } set { labelInfo.Text=value;} }

Chacun ses préférences et ses justifications, nous venons en tout cas de répondre à la première exigence pour faire un code plus propre.

La directive

Dans le fichier .aspx de la page de contenu, il suffit d'ajouter la directive suivante :

<%@ MasterType VirtualPath="~/blabla/LaMasterPageDeMonSite.master" %>

Cette simple directement va instruire l'environnement du vrai type de la page master, et, Ô magie !, c'est la propriété this.Master qui est automatiquement typée correctement !

On peut dès lors reprendre le même code que celui proposé en introduction (celui utilisant FindControl) et le réécrire proprement en bénéficiant d'un typage fort et de tous les contrôles dignes d'un environnement comme ASP.NET :

this.Master.InfoLabel.Text = "info affiché sur la page maître";

On suppose ici avoir utiliser la méthode consistant à publier le label via une propriété. Avec la seconde méthode proposée, encore plus propre, le code sera encore plus simple et lisible :

this.Master.Info = "info affiché sur la page maître";

Conclusion

C'est pas plus joli comme ça ? ! Si, forcément...

Alors maintenant que vous savez que MasterType existe, n'hésitez pas à vous en servir... et ...

Stay Tuned !

Télécharger de la musique sans se faire pincer ? La solution existe !

Pour aborder un sujet qui change de l'informatique, la musique.

C'est un sujet qui me tient tout autant à coeur et même plus que l'informatique. Musicien, compositeur, quand je ne développe pas, je joue (ou je vais à la pèche mais c'est plus rare malgré tout :-) ). Seule la contemplation de la voûte étoilée ou un bon film de SF peut arriver à me distraire de mes claviers, Azerty ou Midi. Bref même si j'en parle moins ici, ce n'est pas la moindre de mes occupations. Et les nouvelles lois anti piratage me concerne forcément, triplement même. En tant que musicien, en tant que membre de la SACEM, et en tant que simple citoyen.

Le pirate tueur de l'Art ?

Les lois contre le piratage de musique sont dénuées de sens, et je ne m'étalerai pas trop de peur de déraper vers un langage plus.. vert ! Toutefois leur seul et véritable argument est que cela tue la "création", et à grand renfort de vedettes(*) trustant déjà l'essentiel des dividendes de la SACEM on nous explique, en gros, que si Johnny ou Cabrel ne peuvent pas sortir leur 253eme album c'est l'art qui meurt... A pleurer.

(*) voici la liste des vendus à la cause des majors, ce n'est pas secret (on comprend bien de quoi je parle, des johnny en fin de carrière qui veulent toucher encore plus de sous, des jeunôts qui voudraient palper autant que leurs aînés, et plein de nains de l'art (avec petit a) qui pensent que ça fera du buzz autour de leur nom de faire partie des 52... J'exagère, dans le tas il y a aussi des sarkozystes, pas mal même). Tiens, le plus amusant, c'est peut-être qu'ils sont jaloux des artistes qui se font vraiment pirater (signe de reconnaissance), car eux, je n'ai aucun mp3 à leur nom, et pareil chez mes amis... Des gros jaloux ces 52 ? Fort possible. Car un artiste piraté est aussi un artiste qui vend, c'est donc pas le mieux placé pour se plaindre en général.

Les 52 vendus, le premier ça me fait de la peine j'avais de l'estime pour lui (sans l'écouter, juste de la sympathie, c'est fini) : Etienne Daho, Christophe Maé, Kery James, Sinik, Francis Cabrel, Patrick Bruel, Jean-Jacques Goldman, Jenifer, Stanislas, Raphaël, M Pokora, Keren Ann, Thomas Dutronc, Eddy Mitchell, Isabelle Boulay, Maxime Le Forestier, Martin Solveig, Marc Lavoine, Calogero, Gérard Darmon, Pascal Obispo, Jacob Devarrieux, Elie Seimoun, Alain Bashung, Bernard Lavilliers, Rachid Taha, Bob Sinclar, Psy4delarime, Abd Al Malik, Anis, André Manoukian, Charles Aznavour, Alain Souchon, Mademoiselle K, Soprano, Arthur H, BB Brunes, Liane Foly, Emmanuelle Seigner, Ridan, Renan Luce, Zita Swoon, Johnny Hallyday, Empyr, Kenza Farah, Shine, Camaro, Diam's, Renaud, Romane Cerda, Cali et la Grande Sophie. Lire la  dépêche AFP sur le site de Yahoo.

La réalité c'est que ce sont les majors qui tuent l'art et la création en bastonnant quelques "vedettes" sur lesquelles elles misent et investissent comme un riche émir investit dans quelques chevaux de course. Cela est-il profitable à l'espèce équine dans son ensemble pour autant ? Certes non. Les riches émirs pourraient arrêter de s'échanger des chevaux à plusieurs millions de dollars, la race équine n'en mourrait pas, elle existe en dehors des "bêtes à concours". La musique c'est pareil. Sans les majors qui se focalisent sur des bêtes à concours, il existe des milliers, des millions peut être même, d'artistes qui ont aussi le droit de s'exprimer et qui dans tous les cas ne touchent absolument rien de la SACEM ! Si demain le piratage était réduit à zéro, Johnny aurait certainement un chèque encore plus gros en fin d'année, mais AUCUN de tous les artistes non affiliés à la SACEM ne toucherait quoi que ce soit (et d'ailleurs les "petits" membres de la SACEM ne touchent rien non plus de toute façon, il faut le savoir, question de pourcentage de passage ... dans les radio vendues aux majors notamment...). Rappelons aussi que les majors affament les artistes : en moyenne c'est 60 eurocents par CD, 30 eurocents un DVD live et 4 eurocent le titre ! Avec de tels "salaires" on voit comment les majors aident l'art et les artistes...

De toute façon Résumer l'Art et surtout la musique à la "danse des canards" ou l'équivalent chez Jhonny, Cabrel et d'autres hasbeen est donc une hérésie, voire un crime contre l'humanité tellement l'art est indissociable de la nature humaine. Tuer le premier c'est tuer la seconde. Et les majors sont des assassins de l'Art.

De l'obligation morale de mettre hors jeu les majors

Face aux nouvelles dérives agressivement sécuritaires et répressives de notre président (petit p) de la République (grand R, la République est une noble idée) contre les méchants pirates il est temps de faire quelque chose. Les majors ont, soi disant, perdu 50% de leur chiffre d'affaire ? Prouvez-leur que leur stratégie répressive va les amener à perdre le reste ! Le système des majors est d'un autre âge, il a vécu, ils se sont goinfrés sur notre dos à chaque occasion, aujourd'hui ils ne servent plus à rien. On n'a pas hésité à mettre sur le carreau les mineurs du Nord, les gars des manufactures de Saint Etienne, les artisans fabriquants de chaussures ou de tissus et tout un tas de gens dont on a balayé l'existence d'un geste "parce que c'est le progrès", le temps est venu de balayer les majors sans plus de ménagement et pour les mêmes raisons !

Acte 1 : Achetez de la musique aux labels indépendants !

En effet il existe des tas de labels indépendants qui eux se mouillent pour proposer des oeuvres vraiment différentes, il y a de tout et je ne ferai pas l'apologie d'un style ou d'un autre, pour moi l'art est forcément multiple. Si vous trippez sur la techno ou le free-jazz ou le rap français ça ne fait aucune différence.  Il y a aussi Internet qui permet aujourd'hui à des artistes et aux petits labels de se faire connaître, voire de vendre en direct leur musique. C'est le sens de l'histoire. Sans les majors.

Les mesures de plus en plus répressives prisent contre les "pirates" sont féodales. Le Roi a toujours protégé les plus riches, ses alliés. Notre président est à la solde de son ami Bush, du libéralisme débridé, à la solde des gens capables de lui offrir des week-end sur des bateaux de luxe pour protéger leur business dans des rapprochements de république bananière, et à la solde des majors et de tous les rois de la finance et de la spéculation grâce à qui il vit bon train pendant que le peuple tire de plus en plus la langue. Il est l'heure de mettre un coup de pied dans la fourmilière. Globalement, politiquement. Mais revenons à la musique pour l'instant...

Je n'appellerai pas à la révolution, même si je la sens et la sais nécessaire, la dernière, celle de  1789 n'a fait qu'instrumentaliser le peuple pour virer les nobles au profit des bourgeois, ce qui n'a pas fait beaucoup progresser le mot "égalité" de notre devise nationale, c'est un simple constat pas une opinion politique... Et puis verser le sang et couper des têtes est à mon goût trop barbare. La révolution doit être silencieuse et efficace, il faut taper, fort, mais pas sur la tête, au portefeuille, la chose la plus sacrée pour ces adorateurs de dividendes.

Au lieu d'acheter de la musique à des majors, achetez à des petits labels indépendants. Découvrez qu'en dehors de Lorie il existe tout un vaste monde, celui de l'Art justement. Au lieu d'écouter les radios "d'Etat" qui bastonnent les "oeuvres" des majors, écouter la radio sur Internet il y a pour tous les goûts. Et pour nourrir votre lecteur MP3, ne téléchargez pas sur la Mule pour vous faire coincer et faire le jeu des tyrans, mais enregistrez la musique des radios Internet ! Inrepérable, légal, vous n'en aurez pas moins au bout d'un certain temps une collection de mp3 à faire pâlir de jalousie les pirates les plus fous !

Acte 2 : Téléchargez gratuitement et sans risque, enregistrez tout simplement !

Pour enregistre de la musique Internet facilement, sans que cela ne soit brouillé par les sons de windows ou autre, surtout n'utilisez pas des programmes qui enregistrent le "mixage stéréo" de votre carte son, le résultat est affreux. Utilisez plutôt un logiciel comme l'excellent (et gratuit) Screamer. Il vous permet de sélectionner la radio et de l'enregistrer (un fichier mp3 par morceau avec son nom, c'est pas merveilleux ça ? !). Bien entendu choisissez des radios de bonne qualité qui émettent en 128k.

Le temps de la "réponse graduée" contre les majors, ces assassins de l'art, ces spéculateurs qui trustent le pouvoir est arrivé. Mais sans jamais lever la main, non simplement en refusant de la mettre au portefeuille. Ils aiment l'argent plus que tout, les en priver c'est leur faire plus de mal que d'assassiner leur famille.

Acte 3 : Choisir de bonnes radio Internet sans pub 

Eclatez vous, "consommez" encore plus de musique qu'avant, mais en bypassant les vampires et en donnant votre argent aux labels indépendants ou bien en subventionnant une radio Internet comme SOMA FM, radio sans pub, soutenue par ses auditeurs et proposant une dizaines de programmation différentes pour tous les goûts. En cherchant un peu sur le Web on trouve pour tous les goûts de la musique de qualité.

ça fait du bien de gueuler un bon coup de temps en temps...

La prochaine fois je vous reparle de C#, c'est promis :-)

Et Stay Tuned !

 Signé un citoyen membre de la SACEM ... (comme quoi ils ne sont pas tous vendus, et comme des centaines de compositeurs je n'ai pas mandaté les 52 crétins pour parler à ma place, leur démarche est une provocation et une traitrise. Que les dieux de la musique leur fasse faire des fausses notes jusqu'à la fin de leurs jours - c'est pas si méchant comme mauvais sort, pour la plupart vous ne verrez pas la différence je vous l'assure !).

Les posters de VS2008 (affectation de touche, référence .NET)

Voic quelques posters à imprimer qui peuvent s'avérer très utiles au bureau ou même pour être geek jusqu'au bout pour décorer sa salle de bain, voire d'autres lieux de méditation intense que la bienséance m'interdit de préciser plus avant mais qui s'avèrent être des sanctuaires de tranquilité propice à la lecture des docs techniques qu'on néglige trop souvent de consulter...

Donner du peps à Linq ! (Linq dynamique et parser d'expressions)

J'ai eu moulte fois ici l'occasion de dire tout le bien que  je pense de LINQ, de sa puissance, de sa souplesse, de sa versatilité (de xml à SQL en passant par les objets et l'Entity Framework).

Mais une petite chose me chagrinait : toute cette belle puissance s'entendait "hard coded". Je veux dire par là que les expressions et requêtes LINQ s'écrivent en C# dans le code et qu'il semblait très difficile de rendre la chose très dynamique, sous entendu dépendant d'expressions tapées à l'exécution de l'application. En un mot, faire du LINQ dynamique comme on fait du SQL dynamique.

Ce besoin est bien réel et ne concerne pas que les sources SQL. Prenez une simple liste d'objets que l'utilisateur peut vouloir trier selon l'une des propriétés ou filtrer selon le contenu des objets... Comment implémenter une telle feature ?

Contourner ce manque en écrivant des parsers, en jonglant avec les expressions lamba et la réflexion n'est pas, il faut l'avouer, ce qu'il y a de plus simple. Mais rassurez-vous chez Microsoft des gens y ont pensé pour nous ! Seulement voila, la chose est assez confidentielle il faut bien le dire, et on ne tombe pas dessus par hasard. Ou alors c'était un jour à jouer au Lotto, voire à contrôler, selon les mauvaises langues, l'emploi du temps de sa femme !

La chose s'appelle "LINQ Dynamic Query Library", un grand nom pour une petite chose puisqu'il s'agit en réalité d'un simple fichier source C# à ajouter à ses applications.  Mais quel fichier source !

Toute la difficulté consiste donc à savoir que ce fichier existe et mieux, où il se cache... C'est là que c'est un peu vicieux, la chose se cache dans un sous-répertoire d'un zip d'exemples Linq/C#, fichier lui-même astucieusement planqué dans la jungle des milliers de téléchargement de MSDN...

Sans plus attendre allez chercher le fichier cliquant ici.

Une fois que vous aurez accepté les termes de la licence ("I Accept" tout en bas à gauche) vous recevrez le fichier "CSharpSamples.zip". Dans ce dernier (dont tout le contenu est vraiment intéressant) aller dans le répertoire "LinqSamples" puis dans le projet "DynamicQuery" vous descendrez dans une autre sous-répertoire appelé lui aussi "DynamicQuery" (non, ce n'est pas un jeu de rôle, juste un téléchargement MSDN!). Et là, le Graal s'y trouve, "Dynamic.cs".

Copiez-le dans vos projets, et ajouter un "using System.Linq.Dynamic". A partir de là vous pourrez utiliser la nouvelle syntaxe permettant de faire du LINQ dynamique. A noter que dans le répertoire de la solution vous trouverez aussi un fichier "Dynamic Expressions.html" qui explique la syntaxe du parser.

Quelles sont les possibilités de LINQ Dynamic Query Library ?

C'est assez simple, pour vous expliquer en deux images je reprend deux captures écrans tirées du blog de Scott Guthrie (un excellent blog à visiter si vous parlez l'anglais).

Voici un exemple de requête LINQ (en VB.NET, si j'avais refait la capture cela aurait été du C#, mais je ne vais pas rouspéter hein ! )

Maintenant voici la même requête utilisant du LINQ dynamique :

Vous voyez l'astuce ? Le filtrage et le tri sont maintenant passés en chaîne de caractères... Bien entendu cette chaîne peut avoir été construite dynamiquement par code (c'est tout l'intérêt) ou bien saisie depuis un TextBox rempli par l'utilisateur.

Ici pas de risque d'attaque par "SQL injection", d'abord parce que LINQ n'est pas limité à SQL et que le problème ne se pose que dans ce cas, mais surtout parce que LINQ to SQL utilise des classes issues d'un modèle de données "type safe" et que par défaut LINQ to SQL est protégé contre les attaques de ce type. Pas de souci à se faire donc.

Pour terminer j'insisterai lourdement sur le fait que LINQ ne se limite pas aux données SQL, et que l'astuce de LINQ dynamique ici décrite s'applique même à LINQ to Object par exemple. Laisser la possibilité à un utilisateur de trier une List<> ou une Collection<>, de la filtrer, tout cela en mémoire et sans qu'il y ait la moindre base de données est bien entendu possible.

LINQ est vraiment une innovation majeure en matière de programmation, pouvoir le dynamiser simplement c'est atteindre le nirvana...

Je vous laisse vous jeter sur vos claviers pour expérimenter du LINQ dynamique, amusez-vous bien !

..et surtout.. Stay tuned !

 

Des skins pour Visual Studio 2008 !

VS 2008 ne se contente pas d'être à mon sens le meilleur EDI jamais créé (et le plus stable aussi comme son prédécesseur), il peut aussi être beau !

Certes VS2008 ou 2005 ne sont pas laids, ce sont des EDI sobres, professionnels et fonctionnels. Mais même si Apple n'est plus un fabriquant de machine adulé mais un vendeur de lecteurs mp3 et de téléphones, il faut bien concéder qu'ils ont modifié en profondeur une chose : le look & feel des machines comme des applications. L'esprit Apple c'est le beau. Et même si nos PC et nos logiciels Windows ont gagné la bataille du fonctionnel, ils sont loin d'avoir gagné la guerre du look !

Ce n'est pas pour rien que Microsoft s'oriente vers Vista et son moteur graphique, que la programmation .NET évolue vers WPF, la programmation web vers Silverlight : l'utilisateur est désormais habitué à la qualité fonctionnelle, il en veut plus, il veut du beau.. Et l'informaticien n'est pas en reste. Il veut que son IDE soit aussi le plus esthétique possible.

Le look de votre VS 2008 vous lasse ? .. Et bien changez de peau !

Il est en effet possible, dans certaines limites, de modifier l'aspect de VS 2008 grâce à une logique classique de "thèmes". Ne rêvez pas, Visual Studio ne se transformera pas en jeu video 3D pour autant ! Mais vous pourrez au moins le relooker un peu. Pour ne pas vous laissez vous emballer pour rien, précisons même que les fameux thèmes jouent principalement sur les couleurs des éditeurs, pas sur l'aspect des fenêtres, leur forme, leur opacité ou toutes ces choses que sous-entend habituellement le mot "thème". Mais bon, vous allez voir, c'est toujours mieux que rien !

D'autant que nul besoin de tripatouiller les réglages de VS puisqu'il existe en téléchargement gratuit des thèmes assez chouettes que vous pouvez installer directement.

Une fois un thème installé dans le répertoire ...\Mes Documents\Visual Studio 2008\Settings vous pouvez l'importer de la façon suivante (j'utilise l'IDE en anglais à vous de traduire donc) :

  • Etape 0 : faites un export/sauvegarde de vos réglages actuels avant de commencer, on ne sait jamais!
  • Tools | Import and Export Settings
  • Import Selected environment settings
  • "No", just import new settings
  • Cliquez sur "Next" et "Import All Settings"

Les fichiers de thèmes ne contiennent que des informations portant sur les fontes et les couleurs, aucun autre paramètres ne sera donc effacé par cette manoeuvre. D'ailleurs un écran précédent l'import vous permettra de choisir dans l'arbre des paramètres ceux à prendre en compte.

où trouver des thèmes ?

Dans le cas où vous souhaiteriez retrouver le look d'origine :

 En cherchant sur le Web vous trouverez certainement d'autres thèmes.

Amusez-vous bien et.. Stay tuned !

Le blues du générateur d'état (sous titré: Et si RDL était la solution ?)

Il n'y a pas que le "Set of" de Delphi qui peut donner le blues (voir ce billet pour comprendre), non, il y a pire, sous tous les langages, depuis toujours, sous tous les OS, l'informaticien a toujours eu le blues des générateurs d'état, et le blues, c'est peu dire...

[EDIT: Voir ce billet plus récent qui propose un tutor complet] 

Les delphistes ont pesté contre QuickReport et ses bugs après avoir ronchonné sur ReportSmith (qui s'en souvient?), Borland l'a remplacé un jour par RaveReport, encore pire, Microsoft intègre de longue date Crystal Report qui n'a jamais eu les faveurs des développeurs (comment peut-il encore exister d'ailleurs si personne ne l'aime ? un mystère), sans trop rien dire tout en le disant sans le dire, Microsoft propose un service de génération d'état dans Sql Server. Quelle drôle d'idée que de le lier au serveur (même s'il y a une logique compréhensible) plutôt que d'en faire un produit à part réellement intégré à VS. Mais peu de gens s'en servent et MS ne semblent pas non plus le promouvoir avec force et vigueur...

Je suis convaincu que les Java-istes, les C-istes, et même les cobolistes (heeuu non, eux ils faisaient les états à la main avec des petites étoiles pour dessiner les cadres), enfin à part les cobolistes donc, je suis convaincu que tous les développeurs du monde ont toujours été déçus par les générateurs d'état.

La faute à qui ? A la nature même des états... Un état cela peut être tout et n'importe quoi. D'un simple "listing" à l'ancienne, jusqu'à la mise en page d'une ordonnance ou d'un rapport d'activité annuel, d'une facture à une liasse fiscale, d'un chèque à un mailing publicitaire... Une vraie liste à la Prévert ! Et chacun de ces documents a ses propres exigences, ses priorités, ses "non négociables". Un mailing avec enveloppe à fenêtre ou une liaisse fiscale pré-imprimée devront se reposer sur un outil très précis au niveau du placements des zones, pour un listing c'est la facilité et la rapidité de mise en page en colonnes, les sous-totaux, les regroupements, les ruptures qui seront essentiels..

Bref, le générateur d'état idéal et parfait n'existe pas. Il en existe de très mauvais (non, je te citerai pas de noms !), d'autres meilleurs, mais aucun n'est adapté à tous les besoins.

RDL vous connaissez ?

Report Definition Language. Une norme de description d'état dérivée de XML, voilà ce qu'est RDL. C'est sur ce langage d'ailleurs que repose le service générateur d'état de SQL Server 2005 et 2008, mais RDL existe en dehors de cette base de données. Et c'est tout là son intérêt !

La description de la norme de novembre 2005 se trouve ici, une lecture édifiante, mais peu passionnante il faut l'avouer.

Le site suivant (ici) regroupe des informations complémentaires sur RDL ainsi que le composant ReportViewer de Microsoft qui s'intègre à Visual Studio (une version VS 2005 et une pour VS 2008 existent).

On trouve même ici un moteur RDL autonome ainsi qu'un designer visuel évitant de trop mettre les mains dans XML. Gratuit et avec les sources, accompagné d'un serveur d'états, il s'agit là d'une base intéressante.

RDL et ses trops rares outils restent encore trop confidentiels, la puissance descriptive du langage est pourtant plus qu'intéressante, la possibilité de requêter des sources SQL mais aussi des services Web, des flux RSS, etc, n'est qu'une des facettes de cette puissante alternative aux générateurs d'état classiques.

RDL est-t-il le générateur d'état idéal ?
Difficile à dire car c'est avant tout un langage, mais justement, là est sa force : les états deviennent descriptifs, "générables" par programmation (fabriquer un fichier XML à coup de WriteLine dans un fichier texte est d'une simplicité enfantine), partageables (RDL est un format ouvert et publié), et les moteurs traitant RDL savent exporter les états en PDF, HTML, CSV, MHT, Texte, RTF, etc..

Il n'y a pas à l'heure actuelle (à ma connaissance) de superbes designers hyper sexy pour RDL (mais VS 2008 intègre un designer visuel, le saviez-vous ?!), l'information est difficile à trouver, c'est le côté "underground" de RDL.. Mais si comme tous les informaticiens de la planète (et peut-être même de quelques exoplanètes!) vous avez le blues du générateur d'état, alors jetez un oeil à RDL, il y a des chances que cela vous séduise. Dans tous les cas vous aurez au moins gagné un sujet de conversation hyper branché pour la machine à café !

Merci qui ? ... Laughing

Alors stay tuned !

Les bonnes adresses Microsoft : Tout sur Visual Studio 2008

Le monde Microsoft est tellement vaste que retrouver certains téléchargements peut s'avérer difficile. Pour vous simplifier la vie voici une liste de bonnes adresses !

Visual Studio 2008

  • Version Express gratuite ( ici )
  • Version payante [ abonndés MSDN seulement ] ( ici )
  • Version d'essaiici )

Visual Studio 2008 SDK 

Kit de développement officiel.
Download Visual Studio 2008 SDK ( Version 1.0  beta 1.1)

Visual Studio 2008 - Exemples

"ASP.NET

  • Exemples et starter kits ici.
Visual Basic Visual C#

Outils VS pour Microsoft Office system 3.0

  • Download Microsoft Visual Studio Tools for the Microsoft Office system ( x86 )

Microsoft Report Viewer Redistributable 2008

  • Microsoft Report Viewer Redistributable 2008 ( ici

Visual Studio 2008 Training Kit

  • Visual Studio 2008 Training Kit ( ici   

Visual Studio 2008 Shell (isolated mode) Redistributable Package

  • Download Visual Studio 2008 Shell (isolated mode) Redistributable Package ( ici )

Visual Studio 2008 Shell (integrated mode) Redistributable Package

  • Download Visual Studio 2008 Shell (integrated mode) Redistributable Package ( ici ) 

 

 

fichiers CHM bloqués ou non lisibles.. la solution au mystère

Certes le format CHM n'est plus "officiellement" le format d'aide préconisé, mais il faut bien convenir qu'on trouve encore beaucoup de ces fichiers : du simple fichier d'aide à des livres entiers, ce format Html compressé et agrémenté d'index et de recherche est compact, pratique et donc encore très utilisé. D'où certainement l'intérêt pour beaucoup d'entre vous de cette petite astuce...

Ne vous est-il jamais arrivé qu'en ouvrant un fichier CHM vous puissiez voir généralement l'index mais que l'affichage de toute page se solde par une page d'erreur du type "page indisponible, impossible d'atteindre la page..." ?

Bien souvent ces fichiers viennent d'Internet suite à un téléchargement parfois depuis des sources nous allons dire peu orthodoxes... De fait se croyant puni par le sort pour son forfait l'infortuné informaticien fouineur finit par jeter le fichier à la corbeille pensant qu'il est "vérolé" et n'osant pas trop faire de réclamation en raison de la provenance du fichier... Mais ne vous moquez pas ! Cette situation arrive aussi avec des fichiers CHM aux sources nobles et parfaitement légitimes, il suffit pour cela que Windows (et le service Pack 2 de XP) ait compris qu'il provienne d'Internet pour que le contenu se retrouve ainsi bloqué !

L'intention de Microsoft est louable dans un tel renforcement de sécurité, mais hélas le message d'erreur affiché est tellement éloigné de la raison réelle que le fichier termine à la poubelle sans qu'on ait pu comprendre qu'il y avait bien plus simple, et surtout que le contenu du fichier était parfaitement accessible ! Dommage non ? .. Quand on pense à tous ces CHM pleins de bonnes informations qui ont été mis injustement à la corbeille... Je propose d'ailleurs une minute de silence..  ... ... Merci.

Donc, le SP2 de XP bloque les fichiers CHM qui proviennent d'Internet, même stockés sur votre disque dur (et non pas depuis un téléchargement en live. Nous parlons bien d'un fichier présent physiquement sur vos disques).

Pour débloquer la situation naviguez dans le répertoire du fichier CHM en question, clic droit, Propriétés, puis choisir... et oui... "Débloquer" ! C'est bête non ?

Je vous laisse pleurer sur les CHM parfaitement valides que vous avez téléchargés ici et là et qui sont depuis longtemps digérés par la corbeille de votre XP, soyez positifs, maintenant cela n'arrivera plus...

 Stay tuned !