<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Pascal Lacroix &#187; développement</title>
	<atom:link href="http://www.pascallacroix.net/blog/tag/developpement/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.pascallacroix.net/blog</link>
	<description>Consultant entrepreneur en nouvelles technologies</description>
	<lastBuildDate>Fri, 25 Jun 2010 20:19:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Le principe d&#8217;ouvert-fermé</title>
		<link>http://www.pascallacroix.net/blog/2010/01/04/le-principe-douvert-ferme/</link>
		<comments>http://www.pascallacroix.net/blog/2010/01/04/le-principe-douvert-ferme/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 06:26:48 +0000</pubDate>
		<dc:creator>Pascal Lacroix</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[développement]]></category>
		<category><![CDATA[philosophie]]></category>

		<guid isPermaLink="false">http://www.pascallacroix.net/blog/?p=195</guid>
		<description><![CDATA[Pour démarrer cette année 2010, je vous présente le principe d&#8217;ouvert-fermé (ou Open-Closed Principle en anglais &#8211; OCP). Il s&#8217;agit d&#8217;une philosophie de développement qui propose une manière de travailler. Je vous la présente car elle primordiale à mes yeux. Qu&#8217;est-ce-que l&#8217;ouvert-fermé? En fait, par ouvert-fermé, il faut comprendre ouvert aux évolutions et fermé aux [...]]]></description>
			<content:encoded><![CDATA[<p>Pour démarrer cette année 2010, je vous présente le <strong>principe d&#8217;ouvert-fermé</strong> (ou <strong>Open-Closed Principle</strong> en anglais &#8211; OCP).</p>
<p>Il s&#8217;agit d&#8217;une philosophie de développement qui propose une manière de travailler. Je vous la présente car elle primordiale à mes yeux.</p>
<p><span id="more-195"></span></p>
<h3>Qu&#8217;est-ce-que l&#8217;ouvert-fermé?</h3>
<p>En fait, par ouvert-fermé, il faut comprendre ouvert aux évolutions et fermé aux modifications.</p>
<p>Cela veut dire qu&#8217;une classe a la capacité d&#8217;être étendue (ajout de nouvelles fonctionnalités), sans pour autant que le code existant qui implémente un comportement soit modifié.</p>
<p>Appliquer le principe OCP permet d&#8217;assurer une architecture évolutive sans allonger la durée des tests et de la maintenance.</p>
<p>Le principe a été énoncé la première fois en 1988 par le Docteur <a title="Bertrand Meyer" href="http://en.wikipedia.org/wiki/Bertrand_Meyer">Bertrand Meyer</a>.</p>
<h3>Pourquoi utiliser OCP?</h3>
<p>OCP impose les règles suivantes:</p>
<ul>
<li>une classe doit être extensibles,</li>
<li>pour ajouter une fonctionnalité ou modifier un comportement, il ne faut pas toucher au code existant.</li>
</ul>
<p>Ceci entraine plusieurs conséquences:</p>
<ul>
<li>L&#8217;extensibilité: il faut donc réfléchir en amont aux extensions possibles. Il faut prévoir dans l&#8217;architecture des points d&#8217;extensions (par héritage, par événements ou autres) ;</li>
<li>Le code testé n&#8217;est pas modifié: ce qui veut dire que les nouveaux <em>bugs</em> apparaitront dans votre nouveau code ;</li>
</ul>
<h3>Un exemple concret</h3>
<p>Dans la pratique, j&#8217;utilise le framework <a href="http://www.asp.net/mvc" target="_blank">ASP.NET MVC</a> pour le développement des applications Web. Ce framework est une sur-couche de ASP.NET de Microsoft.</p>
<p>ASP.NET MVC permet d&#8217;ajouter des attributs sur les méthodes d&#8217;action des controlleurs. Ces attributs permettent de modifier le comportement d&#8217;une action avant ou/et après son exécution.</p>
<p>Prenons un exemple simple:</p>
<ul>
<li>Nous venons d&#8217;écrire une action qui effectue le chargement d&#8217;une liste d&#8217;utilisateurs en fonction du numéro de la page ;</li>
<li>Nous testons notre code (en écrivant par exemple des tests unitaires) ;</li>
<li>Plus tard, nous souhaitons ajouter un nouveau comportement à cette action: imposer l&#8217;authentification de l&#8217;utilisateur avec un rôle précis. Dans ASP.NET MVC, il suffira d&#8217;ajouter l&#8217;attribut <strong>Authorize</strong> sur la méthode pour que le framework demande automatiquement à l&#8217;utilisateur de s&#8217;authentifier lors de l&#8217;appel de cette action.</li>
</ul>
<p>C&#8217;est donc ici un exemple d&#8217;OCP: le code existant de l&#8217;action n&#8217;est pas modifié et pour l&#8217;étendre, il suffit d&#8217;ajouter un attribut avant la méthode.</p>
<p>Voici un exemple en C# pour être plus clair:</p>
<pre class="brush: csharp;">
public ActionResult Index(int page)
{
  List users = _userRepository.GetUsers(page);
  return View(users);
}
</pre>
<p>En appliquant l&#8217;attribut de sécurité, cela donne le code suivant:</p>
<pre class="brush: csharp;">
// On demande d'être authentifié et d'avoir le rôle d'administrateur
[Authorize(Roles=&quot;Admin&quot;)]
public ActionResult Index(int page)
{
  List users = _userRepository.GetUsers(page);
  return View(users);
}
</pre>
<p>Pour en savoir plus sur les attributs et l&#8217;extensibilité, je vous invite à consulter l&#8217;excellent billet de Rob Conery: <a href="http://blog.wekeroad.com/blog/aspnet-mvc-securing-your-controller-actions/" target="_blank">http://blog.wekeroad.com/blog/aspnet-mvc-securing-your-controller-actions/</a>.</p>
<h3>Pour aller plus loin</h3>
<p>J&#8217;espère avoir attiré votre attention sur ce principe. Pourquoi pas essayer de le mettre en place dans vos prochains développements?</p>
<p>Voici quelques liens qui vous permettront d&#8217;en savoir plus sur OCP:</p>
<ul>
<li>Un article de Microsoft: <a href="http://msdn.microsoft.com/fr-fr/magazine/cc546578.aspx" target="_blank">http://msdn.microsoft.com/fr-fr/magazine/cc546578.aspx</a></li>
<li>Un billet de Emmanuel Deloget: <a href="http://blog.emmanueldeloget.com/index.php/2006/09/21/15-le-principe-ouvert-ferme" target="_blank">http://blog.emmanueldeloget.com/index.php/2006/09/21/15-le-principe-ouvert-ferme</a></li>
<li>La présentation de Wikipedia: <a href="http://en.wikipedia.org/wiki/Open/closed_principle" target="_blank">http://en.wikipedia.org/wiki/Open/closed_principle</a></li>
<li>Extensibilité dans ASP.NET MVC: <a href="http://codeclimber.net.nz/archive/2009/04/08/13-asp.net-mvc-extensibility-points-you-have-to-know.aspx" target="_blank">http://codeclimber.net.nz/archive/2009/04/08/13-asp.net-mvc-extensibility-points-you-have-to-know.aspx</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.pascallacroix.net/blog/2010/01/04/le-principe-douvert-ferme/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Popfly va-t-il tuer les développeurs?</title>
		<link>http://www.pascallacroix.net/blog/2007/10/19/popfly-va-t-il-tuer-les-developpeurs/</link>
		<comments>http://www.pascallacroix.net/blog/2007/10/19/popfly-va-t-il-tuer-les-developpeurs/#comments</comments>
		<pubDate>Fri, 19 Oct 2007 08:12:42 +0000</pubDate>
		<dc:creator>Pascal Lacroix</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[développement]]></category>
		<category><![CDATA[mashup]]></category>
		<category><![CDATA[silverlight]]></category>

		<guid isPermaLink="false">http://www.pascallacroix.net/wordpress/?p=70</guid>
		<description><![CDATA[<p>Derrière ce titre un peu choc se cache un outil vraiment révolutionnaire. Microsoft sort un nouveau produit qui risque bien de faciliter en davantage le développement d'applications riches.</p>]]></description>
			<content:encoded><![CDATA[<p>Derrière ce titre un peu choc se cache un outil vraiment révolutionnaire. Microsoft sort un nouveau produit qui risque bien de faciliter en davantage le développement d&#8217;applications riches.</p>
<p><span id="more-70"></span></p>
<p><a href="http://www.popfly.com">Popfly</a>est le dernier né des éditeurs de mashus pour Silverlight. <a href="http://www.silverlight.net">Silverlight</a>, comme vous le savez peut être, est un plugin pour les navigateurs internet qui est la réponse à Adobe Flash. Microsoft veut répliquer face à Flash et <a href="http://www.silverlight.net">Silverlight</a> risque bien de faire peur à Adobe car il apporte des éléments très convaincants (dont le support du codec vidéo VC-1 qui semble encore meilleur que le H264 pour de la vidéo HD en plein écran).</p>
<p>Bon revenons à <a href="http://www.popfly.com">Popfly</a>. Il s&#8217;agit donc d&#8217;un mashup creator. Un mashup est une application créée à partir d&#8217;un mélange de services (en général des services web). <a href="http://www.popfly.com">Popfly</a>permet donc de gérer les connexions entre ces services et de créer des applications pour <a href="http://www.silverlight.net">Silverlight</a>.</p>
<p>L&#8217;avantage de <a href="http://www.popfly.com">Popfly</a>, par rapport à un atelier logiciel, est qu&#8217;il est entièrement visuel: on prend un bloc fonctionnel, on le pose, on en prend un second et on crée une connexion entre les deux. L&#8217;utilisation est simple et accessible à n&#8217;importe quelle personne quasiment: plus besoin d&#8217;être développeur pour créer une application. Voici donc la nouvelle attaque de Microsoft!</p>
<p>Bien sûr, <a href="http://www.popfly.com">Popfly</a> ne va pas mettre tous les développeurs au chômage, bien loin de là! En effet, le logiciel propose quelques blocs par défaut. Ces blocs fournissent des fonctions de base: recherche d&#8217;images, modules de sortie, gestion de flux RSS&#8230; Les développeurs seront chargés de créer des blocs personnalisés pouvant réaliser des fonctionnalités complètement différentes. <a href="http://www.popfly.com">Popfly</a>propose les briques de bases pour créer une application <a href="http://www.silverlight.net">Silverlight</a> rapidement.</p>
<p>Je vous invite à essayer <a href="http://www.popfly.com">Popfly</a> et à me laisse vos commentaires sur le produit. Pour essayer, il suffit d&#8217;avoir un compte Live ID et de vous rendre à l&#8217;adresse du projet: <a href="http://www.popfly.com">www.popfly.com</a>.</p>
<p>Vous pouvez également consulter d&#8217;autres articles sur le même sujet:</p>
<ul>
<li><a href="http://www.clubic.com/actualite-73948-popfly-editeur-mashups-microsoft.html" hreflang="fr">http://www.clubic.com/actualite-73948&#8230;microsoft.html</a></li>
<li><a href="http://www.laboratoire-microsoft.org/news-25564-microsoft-popfly-developpement-facile.html" hreflang="fr">http://www.laboratoire-microsoft.org/&#8230;-facile.html</a></li>
<li><a href="http://www.pcinpact.com/actu/news/36487-popfly-microsoft-silverlight-alpha-invitatio.htm" hreflang="fr">http://www.pcinpact.com/actu/news/36487&#8230;invitatio.htm</a></li>
<li><a href="http://fr.techcrunch.com/2007/10/19/microsoft-lance-popfly-la-creation-dapplications-pour-tous/" hreflang="fr">http://fr.techcrunch.com/2007/10/&#8230;pour-tous/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.pascallacroix.net/blog/2007/10/19/popfly-va-t-il-tuer-les-developpeurs/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Profitons de la sortie de Windows Vista pour faire un retour en arrière</title>
		<link>http://www.pascallacroix.net/blog/2007/01/30/profitons-de-la-sortie-de-windows-vista-pour-faire-un-retour-en-arriere/</link>
		<comments>http://www.pascallacroix.net/blog/2007/01/30/profitons-de-la-sortie-de-windows-vista-pour-faire-un-retour-en-arriere/#comments</comments>
		<pubDate>Tue, 30 Jan 2007 21:13:54 +0000</pubDate>
		<dc:creator>Pascal Lacroix</dc:creator>
				<category><![CDATA[Systèmes d'exploitation]]></category>
		<category><![CDATA[développement]]></category>
		<category><![CDATA[embarqué]]></category>
		<category><![CDATA[système d'exploitation]]></category>
		<category><![CDATA[vista]]></category>

		<guid isPermaLink="false">http://www.pascallacroix.net/wordpress/?p=64</guid>
		<description><![CDATA[<p>La sortie du nouveau système de Microsoft me fait penser que moi aussi je m'étais lancé dans le développement d'un système d'exploitation il y a quelques années...</p>]]></description>
			<content:encoded><![CDATA[<p>La sortie du nouveau système de Microsoft me fait penser que moi aussi je m&#8217;étais lancé dans le développement d&#8217;un système d&#8217;exploitation il y a quelques années&#8230;</p>
<p><span id="more-64"></span></p>
<p>C&#8217;était en 1998 je crois, je sortais avec le bac S en poche et j&#8217;entrais en prépa.</p>
<p>J&#8217;avais pour projet de créer un système d&#8217;exploitation simple et léger pour permettre de le placer dans des systèmes embarqués ou des plateformes peu puissantes. Après études des documentations du processeur Intel 386 (c&#8217;était ma cible car on trouvait énormement de documentation à ce sujet à l&#8217;époque déjà), j&#8217;ai étudié différents systèmes proposés par le monde open source. Il y avait déjà plusieurs exemples de système gratuit à l&#8217;époque: linux, minix, freedos, reactos.</p>
<p>Mon objectif était simple: créer un petit système minimaliste qui permettrait à chacun d&#8217;étudier les mécanismes des systèmes d&#8217;exploitations, tout en permettant de partir de ce système comme base de développement plus complexe.</p>
<p>Par manque de temps, je n&#8217;ai pas pu avancer réellement sur ce projet. Le système LittleOS (c&#8217;est son nom) est donc devenu un projet qui s&#8217;est terminé assez rapidement (j&#8217;ai travaillé environ 2 ans dessus, quelques heures par mois).</p>
<p>Si vous souhaitez en savoir un peu plus, je vous invite à consulter le <a href="http://littleos.free.fr">site du système LittleOS</a>. Attention, il s&#8217;agit d&#8217;un (très) vieux site et j&#8217;avoue que je ne suis pas très fier des couleurs que j&#8217;ai pu choisir à l&#8217;époque (elles sont assez vives!).</p>
<p>Le site de <a href="http://littleos.free.fr">LittleOS</a> propose quelques documents mais surtout l&#8217;accès aux sources du système d&#8217;exploitation. Je tiens à vous prévenir car il s&#8217;agit d&#8217;une version préliminaire et donc pas très fonctionnelle.</p>
<p>La dernière version en ligne (0.3.2) propose les fonctionnalités suivantes:</p>
<ul>
<li>Gestion d&#8217;une console simpliste (affichage de messages),</li>
<li>Gestion des interruptions et des exceptions du CPU,</li>
<li>Gestion des allocations mémoire (type malloc/free),</li>
<li>Accès à la pagination (pour gérer le mapping mémoire physique/mémoire logique).</li>
</ul>
<p>Vous pouvez aussi accéder directement à la page des téléchargements: <a href="http://littleos.free.fr/?lang=fr&amp;pg=files">Téléchargement des sources de LittleOS</a>.</p>
<p>Si vous avez des questions au sujet de ce projet, n&#8217;hésitez pas à me contacter.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pascallacroix.net/blog/2007/01/30/profitons-de-la-sortie-de-windows-vista-pour-faire-un-retour-en-arriere/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Firefox devient un outil de développement web</title>
		<link>http://www.pascallacroix.net/blog/2007/01/17/firefox-devient-un-outil-de-developpement-web/</link>
		<comments>http://www.pascallacroix.net/blog/2007/01/17/firefox-devient-un-outil-de-developpement-web/#comments</comments>
		<pubDate>Wed, 17 Jan 2007 22:34:36 +0000</pubDate>
		<dc:creator>Pascal Lacroix</dc:creator>
				<category><![CDATA[Divers]]></category>
		<category><![CDATA[développement]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.pascallacroix.net/wordpress/?p=61</guid>
		<description><![CDATA[<p>Le navigateur bien connu et conforme aux standards devient aujourd'hui un outil indispensable au développement Web.</p>]]></description>
			<content:encoded><![CDATA[<p>Le navigateur bien connu et conforme aux standards devient aujourd&#8217;hui un outil indispensable au développement Web.</p>
<p><span id="more-61"></span></p>
<p>Firefox est avant tout un navigateur gratuit et conforme aux normes. Il est facile à étendre grâce aux centaines de modules disponibles (voir par exemple sur <a href="http://extensions.geckozone.org/Firefox/" hreflang="fr">Geckozone</a>).</p>
<p>Certaines extensions apportent de nouvelles fonctionnalités de navigation ou de consultation (par exemple lire un flux RSS, ajouter un vérificateur orthographique pour valider les formulaires avant soumission).</p>
<p>Pour un développeur Web, Firefox apporte des extensions qui simplifient le développement et permettent de voir le résultat de manière immédiate. Du coup, ce navigateur peut désormais être utilisé comme environnement de développement pour des pages web (à condition de connaitre le langage HTML bien sûr).</p>
<p>DevelopperToolbar et Firebug sont deux extensions indispensables. Ce billet les présente.</p>
<h4>Web Developper Toolbar</h4>
<p>Comme son nom l&#8217;indique, l&#8217;extension Web Developper Toolbar permet d&#8217;ajouter des fonctionnalités orientées développement web. Cette barre ajoute des fonctions pour inspecter le contenu des pages (code HTML ou CSS par exemple), mais aussi de valider ces pages en utilisant les services en ligne. Il est également possible de parcourir visuellement l&#8217;arbre syntaxique de la page en survolant les éléments de la page en cours. Cette extension permet d&#8217;afficher un page web sans les images, sans la feuille de style, bref, elle permet de la tester dans différentes configuration.</p>
<h3>Quelques fonctionnalités intéressantes</h3>
<ul>
<li>Activer/Désactiver l&#8217;affichage des images,</li>
<li>Vérifier les attributs &laquo;&nbsp;alt&nbsp;&raquo; sur les images,</li>
<li>Activer/Désactiver/Modifier les feuilles de styles,</li>
<li>Vérifier si les codes HTML et CSS sont valides (en utilisant les validateurs du W3C),</li>
<li>Afficher le chemin d&#8217;un élément surligné (en passant la souris),</li>
<li>Désactiver le cache, l&#8217;utilisation de java ou de javascript.</li>
<li>Afficher les informations de la page: id des éléments, liens, les différents média chargés (permet de visualiser chaque image et de la sauvegarder).</li>
</ul>
<h3>Exemples d&#8217;utilisation</h3>
<p>Voici quelques captures qui vous montrent à quoi ressemble cette extension et son utilisation.</p>
<p>Regardons ce que devient Google si on active l&#8217;aperçu sur écran de petite taille (par exemple PDA):</p>
<p><a href="/blog/wp-content/uploads/2007-dotclear/firefox/extensions_web/capture_google_petit_ecran.jpg" hreflang="fr"><img src="/blog/wp-content/uploads/2007-dotclear/firefox/extensions_web/capture_google_petit_ecran_petit.jpg" /></a></p>
<p>On remarque que ce site semble bien conçu pour ce type d&#8217;affichage.</p>
<p>Web Developper Toolbar permet aussi de tester l&#8217;accessibilité d&#8217;un site en désactivant les images:</p>
<p><a href="/blog/wp-content/uploads/2007-dotclear/firefox/extensions_web/capture_tf1_sans_images.jpg" hreflang="fr"><img src="/blog/wp-content/uploads/2007-dotclear/firefox/extensions_web/capture_tf1_sans_images_petit.jpg" /></a></p>
<p>D&#8217;après ce qu&#8217;on peut voir, le site de <a href="http://www.tf1.fr" hreflang="fr">TF1</a> n&#8217;est pas vraiment adapté si on désactive les images. Il n&#8217;est donc pas accessibles aux personnes mal-voyantes par exemple.</p>
<p>Je vous ai présenté quelques fonctions de cette extension. J&#8217;espère que vous aurez la curiosité de l&#8217;installer et de me donner vos impressions.</p>
<h3>Pour aller plus loin</h3>
<p>Rendez-vous à la page de l&#8217;extension <a href="https://addons.mozilla.org/firefox/60/" hreflang="en">Web Developer Toolbar</a>.</p>
<p>Vous pouvez également retrouver des informations complémentaires sur la page du développeur: <a href="http://chrispederick.com/work/webdeveloper/" hreflang="en">http://chrispederick.com/work/webdeveloper/</a>.</p>
<h4>Firebug</h4>
<p>Cette extension permet de debugger et de valider le développement AJAX, DHTML et Javascript. L&#8217;extension permet d&#8217;afficher le DOM d&#8217;une page, de sélectionner une portion et d&#8217;inspecter les requêtes effectuées par le navigateur.</p>
<h3>Fonctionnalités</h3>
<ul>
<li>Modification en temps réel du code HTML ou CSS (vous pouvez aussi voir instantannement le résultat),</li>
<li>Débuggage javascript: espions et points d&#8217;arrêts,</li>
<li>Analyse des accès réseau: une page donne la liste des requêtes avec les réponses.</li>
<li>Inspection d&#8217;un élément donné (permet de sélectionner une portion de code et de travailler ensuite celui-ci),</li>
<li>Inspection du DOM du document.</li>
</ul>
<h3>Exemples d&#8217;utilisation</h3>
<p>Pour essayer cette extension, j&#8217;ai simplement démarré Firebug sur mon blog et j&#8217;ai essayé de modifier le titre du premier billet.</p>
<p>L&#8217;interface affiche une zone de saisie lorsque l&#8217;on clique sur un élément modifiable:</p>
<p><img src="/blog/wp-content/uploads/2007-dotclear/firefox/extensions_web/capture_modification_live.jpg" /></p>
<p>Après la modification, le rendu se met à jour et donne ceci:</p>
<p><img src="/blog/wp-content/uploads/2007-dotclear/firefox/extensions_web/capture_resultat_modification.jpg" /></p>
<p>Ensuite, je me suis intéressé de plus prêt à la fonction d&#8217;analyse des requêtes (pour vérifier le chargement des éléments de ma page d&#8217;accueil). L&#8217;extension me donne le résultat suivant:</p>
<p><a href="/blog/wp-content/uploads/2007-dotclear/firefox/extensions_web/capture_firebug_net.jpg" hreflang="fr"><img src="/blog/wp-content/uploads/2007-dotclear/firefox/extensions_web/capture_firebug_net_petit.jpg" /></a></p>
<p>Finalement, je me rends compte que le temps total de chargement est de 4,5 secondes (1and1 n&#8217;est pas très performant!). Le résultat donne la liste de chaque élément. Lorsqu&#8217;on passe la souris sur un élément, l&#8217;extension affiche les détails (pour une image celle-ci est affichée, pratique non?).</p>
<h3>Pour aller plus loin</h3>
<p>Cette extension est un composant indispensable pour le développeur HTML/Javascript. La possibilité de mettre des points d&#8217;arrêts vous fera gagner beaucoup de temps de débuggage.</p>
<p>Je vous invite à consulter la page principale de l&#8217;extension <a href="http://getfirebug.com/" hreflang="en">GetFirebug</a>.</p>
<h3>Quelques autres blogs qui parlent des deux extensions:</h3>
<ul>
<li><a href="http://pablo.rauzy.free.fr/?/blog/post/FireBug-fait-mieux-que-Web-Developer.html" hreflang="fr">p4bl0</a>,</li>
<li><a href="http://blog.developpez.com/index.php?blog=69&amp;title=internet_explorer_developer_toolbar&amp;more=1&amp;c=1&amp;tb=1&amp;pb=1" hreflang="fr">Oh my blog (Developpez.com)</a>,</li>
<li><a href="http://blogzinet.free.fr/index.php?2006/01/03/863-web-developer-extension-10" hreflang="fr">Blogzinet</a>.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.pascallacroix.net/blog/2007/01/17/firefox-devient-un-outil-de-developpement-web/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Introduction aux itérateurs</title>
		<link>http://www.pascallacroix.net/blog/2006/10/25/introduction-aux-iterateurs/</link>
		<comments>http://www.pascallacroix.net/blog/2006/10/25/introduction-aux-iterateurs/#comments</comments>
		<pubDate>Wed, 25 Oct 2006 11:37:42 +0000</pubDate>
		<dc:creator>Pascal Lacroix</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[développement]]></category>
		<category><![CDATA[itérateur]]></category>
		<category><![CDATA[pattern]]></category>

		<guid isPermaLink="false">http://www.pascallacroix.net/wordpress/?p=55</guid>
		<description><![CDATA[<p>Cet article présente les itérateurs tels qu'ils sont définis dans le framework 1.0/1.1 et 2.0. Il propose tout d'abord une présentation de l'implémentation dans le framework 1.0, présente ensuite les nouveautés dans la version 2.0 et donne finalement quelques exemples d'utilisations bien pratiques.</p>]]></description>
			<content:encoded><![CDATA[<p>Cet article présente les itérateurs tels qu&#8217;ils sont définis dans le framework 1.0/1.1 et 2.0. Il propose tout d&#8217;abord une présentation de l&#8217;implémentation dans le framework 1.0, présente ensuite les nouveautés dans la version 2.0 et donne finalement quelques exemples d&#8217;utilisations bien pratiques.</p>
<p><span id="more-55"></span></p>
<h3>Définition d&#8217;un itérateur</h3>
<p>Un itérateur est un design pattern utilisé couramment dans les langages objets de haut niveau comme Java ou C#. Il permet de parcourir une liste d&#8217;éléments de manière ordonnée dans avoir à se soucier de la manière dont sont stockés les éléments. C&#8217;est un design pattern de comportement qui permet de parcourir de manière unique une collection d&#8217;objet. Pour plus d&#8217;informations sur les designs pattern en général, je vous invite à consulter l&#8217;excellent article trouvé sur Wikipédia: <a href="http://fr.wikipedia.org/wiki/Design_pattern" hreflang="fr">Design Pattern</a>, <a href="http://fr.wikipedia.org/wiki/It%C3%A9rateur_%28motif_de_conception%29" hreflang="fr">Iterateur</a></p>
<h3>Fonctionnement des itérateurs dans .NET 1.0/1.1</h3>
<h4>Utilisation d&#8217;un itérateur</h4>
<p>Vous avez peut être déjà utilisé des itérateurs dans .NET sans le savoir. Microsoft a développé un ensemble de classes dont beaucoup sont utilisables comme des itérateurs. En réalité, il est possible d&#8217;itérer sur un objet dès le moment qu&#8217;il implémente l&#8217;interface IEnumerable.</p>
<p>Beaucoup de collections, listes, tables de hashages implémentent cette interface. Grâce à cela, il est possible d&#8217;utiliser l&#8217;opérateur foreach de C# pour itérer sur une collection d&#8217;objet.</p>
<p>Voici un exemple très simple:</p>
<pre class="brush: csharp;">
ArrayList liste = new ArrayList();
liste.Add(&amp;quot;hello&amp;quot;);
liste.Add(&amp;quot;bonjour&amp;quot;);
liste.Add(&amp;quot;au revoir&amp;quot;);
liste.Add(&amp;quot;bye&amp;quot;);

foreach (string element in liste)
{
    Console.WriteLine(element);
}
</pre>
<p>Cet exemple affiche ceci sur la sortie console:</p>
<pre>
hello
bonjour
au revoir
bye
</pre>
<p>Rien d&#8217;extraordinaire c&#8217;est vrai mais nous avons tout de même réussi à parcourir une liste de manière très simple. Ce fonctionnement est utilisable pour n&#8217;importe quel type d&#8217;objet tant que le conteneur implémente IEnumerable.</p>
<h4>Implémentation</h4>
<p>L&#8217;interface IEnumerable contient la méthode suivante:</p>
<pre class="brush: csharp;">
IEnumerator GetEnumerator()
</pre>
<p>Cette méthode doit retourner une instance de type IEnumerator. Cette interface contient les méthodes suivantes:</p>
<pre class="brush: csharp;">
object Current { get; }
bool MoveNext()
void Reset()
</pre>
<p>La propriété Current retourne l&#8217;élément courant de la collection. La méthode MoveNext permet de passer à l&#8217;élément suivant. Elle retourne false quand la collection est arrivée à la fin. La méthode Reset permet de réinitialiser la collection pour retourner sur le premier élément.</p>
<h4>Exemple simple</h4>
<p>Voyons de plus près comment créer un itérateur simple. Dans mon exemple, j&#8217;utilise comme nom de classe OldIterator, en référence aux itérateurs de .NET 1.0/1.1. Les itérateurs de .NET 2.0 fonctionnent un peu différemment. (Le code source est proposé à la fin de cette partie)</p>
<h5>Première étape: créer une classe qui implémente IEnumerable</h5>
<pre class="brush: csharp;">
class OldIterator: IEnumerable
{
    private string[] m_Values = { &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot;, &amp;quot;d&amp;quot; };
#region IEnumerable Members
    public IEnumerator GetEnumerator()
    {
        return new OldIteratorEnumerator(this);
    }
  #endregion
}
</pre>
<p>Cet exemple présente deux parties: un liste d&#8217;éléments fixe qui contient nos valeurs et la méthode GetEnumerator qui permet d&#8217;utiliser cette classe avec foreach.</p>
<h5>Deuxième étape: créer une classe qui implémente IEnumerator</h5>
<p>Une pratique courante est d&#8217;inclure la classe énumerateur dans la classe IEnumerable. Ceci permet de partager facilement les données de deux classes (la sous-classe aura accès aux membres de la classe parente). Il suffit donc d&#8217;ajouter le code suivant dans la classe OldIterator:</p>
<pre class="brush: csharp;">
internal class OldIteratorEnumerator: IEnumerator
{
    private OldIterator m_Parent;
    private int m_Index;
    public OldIteratorEnumerator(OldIterator parent)
    {
        m_Parent    = parent;
        m_Index     = -1;
    }
    #region IEnumerator Members
    /// &amp;lt;summary&amp;gt;
    /// Retourne l'objet courant.
    /// &amp;lt;/summary&amp;gt;
    public object Current
    {
         get
         {
             Console.WriteLine(&amp;quot;### Appel de Current&amp;quot;);
             if (m_Index &amp;amp;lt; 0)
                throw new ApplicationException(&amp;quot;L'index n'a pas encore été initialisé. Il faut appeler la méthode MoveNext en premier.&amp;quot;);
             return m_Parent.m_Values[m_Index];
         }
    }
    /// &amp;lt;summary&amp;gt;
    /// Passer à l'élément suivant.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;true s'il y a encore des éléments après, false si c'est la fin.&amp;lt;/returns&amp;gt;
    public bool MoveNext()
    {
         bool resultat;
         m_Index++;
         if (m_Index &amp;amp;gt;= m_Parent.m_Values.Length)
             resultat = false;
         else
             resultat = true;
         Console.WriteLine(&amp;quot;### Appel de MoveNext(resultat={0})&amp;quot;, resultat);
         return resultat;
    }
    /// &amp;amp;lt;summary&amp;amp;gt;
    /// Réinitialise le pointeur d'élément pour retourner au premier.
    /// &amp;amp;lt;/summary&amp;amp;gt;
    public void Reset()
    {
         Console.WriteLine(&amp;quot;### Appel de Reset&amp;quot;);
         m_Index = -1;
    }
    #endregion
 }
</pre>
<h5>Trosième étape: écriture d&#8217;une classe de test</h5>
<p>Nous avons fait la plus grosse partie du travail, la classe de test montre comme utiliser notre itérateur.</p>
<pre class="brush: csharp;">
class TestIterateur
{
         static void Main(string[ args)
         {
           OldIterator iterator = new OldIterator();
           Console.WriteLine(&amp;quot;Les valeurs de l'iterateur:&amp;quot;);
           foreach (string value in iterator)
           {
                Console.WriteLine(&amp;quot;--&amp;amp;gt; &amp;quot; + value);
            }
            Console.ReadLine();
        }
 }
</pre>
<p>Cet exemple affiche ceci dans la console:</p>
<pre>
Les valeurs de l'iterateur:
### Appel de MoveNext(resultat=True)
### Appel de Current --&gt; a
### Appel de MoveNext(resultat=True)
### Appel de Current --&gt; b
### Appel de MoveNext(resultat=True)
### Appel de Current --&gt; c
### Appel de MoveNext(resultat=True)
### Appel de Current --&gt; d
### Appel de MoveNext(resultat=False)</pre>
<p>Le code source est disponible dans l&#8217;archive suivante: <a href="/donnees/sources/IteratorsTest.zip" hreflang="fr">IteratorsTest.zip</a> (4ko)</p>
<h4>Fonctionnement interne</h4>
<p>En analysant le résultat de l&#8217;exemple précédant, nous pouvons imaginer le fonctionnement de l&#8217;opérateur foreach.</p>
<pre class="brush: csharp;">
foreach (string element in iterator)
{
     Console.WriteLine(element);
}
</pre>
<p>Le compilateur génère l&#8217;équivalent du code suivant:</p>
<pre class="brush: csharp;">
while (iterator.MoveNext())
{
     string element = iterator.Current as string;
     Console.WriteLine(element);
}
</pre>
<p>Et voilà pourquoi il est plus facile d&#8217;utiliser l&#8217;opérateur foreach. La syntaxe est plus simple à coder et plus facile à comprendre. Ce chapitre vous a présenté le fonctionnement des itérateurs dans .NET 1.0/1.1. C&#8217;est un concept simple mais qu&#8217;il faut connaître car ils sont utilises partout dans le framework .NET. De plus, les itérateurs vous apportent de la souplesse dans le codage. Plus besoin de connaître la taille d&#8217;une liste, d&#8217;initialiser un curseur au premier élément, etc. Le chapitre suivant présentera les itérateurs dans .NET 2.0.</p>
<h3>Fonctionnement des itérateurs dans .NET 2.0</h3>
<h4>Utilisation d&#8217;un itérateur</h4>
<p>.NET 2.0 introduit un nouveau moyen pour implémenter facilement des itérateurs. Néanmoins, l&#8217;utilisation d&#8217;un itérateur est identique:</p>
<pre class="brush: csharp;">
foreach TypeElement element in liste_elements
{
     // Traiter 'element'.
}
</pre>
<p>La nouveauté par rapport à .NET 1.0/1.1 est l&#8217;introduction du mot clé <strong>yield</strong>. De plus, avec la possiblité d&#8217;utilier des generics depuis .NET 2.0, il est désormais possible de créer des itérateurs typés ce qui rend le code plus robuste (les erreurs sont détectables plus tôt par le compilateur).</p>
<h4>Implémentation</h4>
<p>Grâce au mot-clef yield, vous pourrez créer des itérateurs typés très facilement puisque le compilateur va générer un grande partie du code. yield permet de retourner une collection d&#8217;élément automatiquement. Le compilateur s&#8217;occupe de générer le code nécessaire.</p>
<h4>Exemple simple</h4>
<p>Voyons un petit exemple. Nous allons créer un itérateur qui retourne des entiers. Par contre, par rapport à l&#8217;exemple de .NET 1.0/1.1, désormais nous n&#8217;avons plus besoin de mettre en place l&#8217;index, la méthode MoveNext, Reset et la propriété Current. Tout ceci est fait par le compilateur.</p>
<pre class="brush: csharp;">
public class PowerIterator: IEnumerable&amp;amp;lt;int&amp;amp;gt;
{
     private int m_Number, m_Exponent;
     public PowerIterator(int number, int exponent)
     {
         m_Number   = number;
         m_Exponent = exponent;
     }
     // &amp;amp;lt;summary&amp;amp;gt;
     // Méthode statique qu'on peut appeler simple par PowerIterator.Power.
     // Elle retourne un itérateur d'entiers qui représente la suite q^n avec
     // q = number et n = exponent.
     // &amp;amp;lt;/summary&amp;amp;gt;
     // &amp;amp;lt;param name=&amp;quot;number&amp;quot;&amp;amp;gt;&amp;amp;lt;/param&amp;amp;gt;
     // &amp;amp;lt;param name=&amp;quot;exponent&amp;quot;&amp;amp;gt;&amp;amp;lt;/param&amp;amp;gt;
     // &amp;amp;lt;returns&amp;amp;gt;&amp;amp;lt;/returns&amp;amp;gt;
     public static IEnumerable&amp;amp;lt;int&amp;amp;gt; Power(int number, int exponent)
     {
         int counter = 0;
         int result = 1;
         while (counter &amp;amp;lt; exponent)
         {
             result = result * number;
             yield return result;
             counter++;
         }
     }

     #region IEnumerable&amp;amp;lt;int&amp;amp;gt; Members
     public IEnumerator&amp;amp;lt;int&amp;amp;gt; GetEnumerator()
     {
         return Power(m_Number, m_Exponent).GetEnumerator();
     }
     #endregion

     #region IEnumerable Members
     System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
     {
         return Power(m_Number, m_Exponent).GetEnumerator();
     }
     #endregion
}
</pre>
<p>Cette classe mérite quelques explications:</p>
<ul>
<li>Tout d&#8217;abord, on commence par indiquer qu&#8217;on implémente un itérateur de type int avec l&#8217;interface IEnumerable&lt;int&gt;,</li>
<li>Il y a deux méthodes dans cette interface: une méthode typée et une autre méthode non typée (pour rester compatible avec la version 1.0/1.1),</li>
<li>Chacun de ces méthodes retourne un énumérateur de type IEnumerator grâce à la méthode Power,</li>
<li>La méthode Power retourne une suite de nombres qui représente les puissances d&#8217;un entier passé en argument.</li>
</ul>
<p>Pour utiliser cet itérateur, voici une petite classe de démonstration. Elle propose deux moyens d&#8217;accès:</p>
<ul>
<li>soit en instanciant l&#8217;itérateur et en utilisant le mot-clef foreach sur cette instance (méthode utilisée avec .NET 1.0/1.1),</li>
<li>soit en appelant directement la méthode Power qui retourne l&#8217;itérateur sous la forme IEnumerable&lt;int&gt;.</li>
</ul>
<pre class="brush: csharp;">
class Program
{
     static void Main(string[ args)
     {
         PowerIterator iterator = new PowerIterator(2, 5);
         // L'utilisation d'un itérateur typé permet de détecter une erreur
         // si on utilise le mauvais type en tant qu'élément.
         Console.WriteLine(&amp;quot;Puissances de 2:&amp;quot;);
         foreach (int n in iterator)
         {
             Console.WriteLine(n);
         }

         Console.WriteLine();
         // Un moyen encore plus simple pour accéder à l'itérateur:
         Console.WriteLine(&amp;quot;Puissances de 3:&amp;quot;);
         foreach (int n in PowerIterator.Power(3, 5))
         {
             Console.WriteLine(n);
         }
         Console.ReadLine();
     }
}
</pre>
<p>Comme vous pouvez le constater, l&#8217;utilisation d&#8217;un itérateur est toujours aussi simple. Par contre, l&#8217;implémentation a été encore simplifiée puisqu&#8217;il suffit de générer une liste d&#8217;élément et de les retourner avec yield.</p>
<p>Cependant, avant d&#8217;utiliser ce mécanisme partout dans votre code, il convient de savoir ce que fait vraiment le compilateur. En effet, en ignorant son fonctionnement, on pourrait se retrouver avec une application lente ou qui ne fonctionne pas comme il faut. L&#8217;ensemble des codes sources est disponible dans l&#8217;archive: IteratorsDotnet2.zip</p>
<h4>Fonctionnement interne</h4>
<h5>Première approche</h5>
<p>Pour arriver à comprendre le fonctionnement de l&#8217;opérateur yield, j&#8217;ai utilisé l&#8217;outil Reflector .NET (de Lutz Roeder) qui permet de désassembler le code et de générer une représentation équivalente en C#. Voici une représentation du code généré par le compilateur pour notre itérateur (les noms générés ont été traduits à la main pour plus de compréhension):</p>
<pre class="brush: csharp;">
internal class PowerIterator : IEnumerable&amp;amp;lt;int&amp;amp;gt;, IEnumerable
{
      // Methods
      public PowerIterator(int number, int exponent);
      public IEnumerator&amp;amp;lt;int&amp;amp;gt; GetEnumerator();
      public static IEnumerable&amp;amp;lt;int&amp;amp;gt; Power(int number, int exponent);
      IEnumerator IEnumerable.GetEnumerator();

      // Fields
      private int m_Exponent;
      private int m_Number;

      // Nested Types
      private sealed class InternalPowerIterator : IEnumerable&amp;amp;lt;int&amp;amp;gt;, IEnumerable,          IEnumerator&amp;amp;lt;int&amp;amp;gt;, IEnumerator, IDisposable
      {
            // Methods
            public InternalPowerIterator(int state);
            private bool MoveNext();
            IEnumerator&amp;amp;lt;int&amp;amp;gt; IEnumerable&amp;amp;lt;int&amp;amp;gt;.GetEnumerator();
            IEnumerator IEnumerable.GetEnumerator();
            void IEnumerator.Reset();
            void IDisposable.Dispose();

            // Properties
            int IEnumerator&amp;amp;lt;int&amp;amp;gt;.Current { get; }
            object IEnumerator.Current { get; }

            // Fields
            private int m_state;
            private int m_current;
            public int m_exponent;
            public int m_number;
            public int m_counter;
            public int m_result;
            public int exponent;
            public int number;
      }
}
</pre>
<p>En analysant rapidement ce code, nous constatons que le compilateur C# a généré une classe (ici InternalPowerIterator). Cette classe implémente les différentes interfaces pour les itérateurs et la gestion mémoire du garbage collector (IDisposable). Les méthodes PowerIterator.GetEnumerator n&#8217;ont pas changé.</p>
<p>La méthode PowerIterator.Power est décrite par le code suivant:</p>
<pre class="brush: csharp;">
public static IEnumerable&amp;amp;lt;int&amp;amp;gt; Power(int number, int exponent)
{
      PowerIterator.InternalPowerIterator result = new PowerIterator.InternalPowerIterator(-2);
      result.m_number = number;
      result.m_exponent = exponent;
      return result;
}
</pre>
<p>Cette méthode instancie la classe InternalPowerIterator, initialise ses membres puis retourne le résultat. Nous pouvons donc en déduire que le compilateur génère automatiquement une classe interne qui sera utilisée pour notre itérateur. La méthode Power permet d&#8217;instancier cette classe généré.</p>
<h5>Etude de la classe générée</h5>
<p>Cette classe contient un ensemble de méthodes que nous allons analyser en détails.</p>
<p><strong>Constructeur</strong></p>
<p>Le constructeur de InternalPowerIterator prend en paramètre un entier qui indique un état (state).</p>
<p><strong>MoveNext</strong></p>
<pre class="brush: csharp;">
private bool MoveNext()
{
     switch (this.m_state)
     {
         case 0:
               this.m_state = -1;
               this.m_counter = 0;
               this.m_result = 1;
               while (this.m_counter &amp;amp;lt; this.exponent)
               {
                     this.m_result *= this.number;
                     this.m_current = this.m_result;
                     this.m_state = 1;
                     return true;
                  Label_0060:
                     this.m_state = -1;
                     this.m_counter++;
               }
               break;
         case 1:
               goto Label_0060;
      }
      return false;
}
</pre>
<p>Cette méthode nous en apprend plus sur l&#8217;attribut m_state. Il s&#8217;agit très probablement de l&#8217;état d&#8217;un automate. En effet, en regardant le code switch, nous remarquons qu&#8217;il s&#8217;agit du code d&#8217;un automate à état très simple. Celui-ci ne gère que trois états: -2, 0 et 1. L&#8217;état -2 est réservé et indique probablement que l&#8217;automate n&#8217;est pas dans un état correcte. L&#8217;état 0 est celui qui initialise les membres de la classe est début la boucle while. L&#8217;état 1 permet de continuer la boucle while à l&#8217;aide du goto.</p>
<p><strong>GetEnumerator</strong></p>
<pre class="brush: csharp;">
IEnumerator&amp;amp;lt;int&amp;amp;gt; IEnumerable&amp;amp;lt;int&amp;amp;gt;.GetEnumerator()
{
    PowerIterator.InternalPowerIterator result;
    // Comparaison de l'état actuel avec l'état -2 (non initialisé).
    if (Interlocked.CompareExchange(ref this.m_state, 0, -2) == -2)
    {        // Si m_state = -2, alors m_state = 0 et retourner la mÃªme instance.
        result = this;
    }
    else
    {
        // Sinon retourner une nouvelle instance initialisée.
        result = new PowerIterator.InternalPowerIterator(0);
    }
    result.number = this.m_number;
    result.exponent = this.m_exponent;
    return result;
}

IEnumerator IEnumerable.GetEnumerator() {
     // Retourne une énumérateur à partir de la méthode IEnumerable&amp;amp;lt;int&amp;amp;gt;.GetEnumerator().
     return this.System.Collections.Generic.IEnumerable&amp;amp;lt;System.Int32&amp;amp;gt;.GetEnumerator();
}
</pre>
<p>La première méthode est très importante pour cette classe. C&#8217;est elle qui permet d&#8217;initialiser la valeur de m_state (l&#8217;état de l&#8217;automate). Elle utilise la méthode Interlocked.CompareExchange qui permet une comparaison/échange thread-safe et retourne une instance de son propre type. Pour le résultat, l&#8217;état est initialisé à 0.</p>
<p><strong>Reset</strong></p>
<p>Le code génère une exception indiquant que la méthode n&#8217;est pas implémentée. Reset() n&#8217;est donc pas supporté dans .NET 2.0.</p>
<p><strong>Dispose</strong></p>
<p>Cette méthode ne contient rien pour le moment.</p>
<p><strong>La propriété Current</strong></p>
<pre class="brush: csharp;">
int IEnumerator&amp;amp;lt;int&amp;amp;gt;.Current
{
      get
      {
            return this.m_current;
      }
}

object IEnumerator.Current
{
      get
      {
            return this.m_current;
      }
}
</pre>
<p>Rien à dire: les deux méthodes retournent l&#8217;élément courant.</p>
<p><strong>Analyse des observations</strong></p>
<p>Nous remarquons que le code généré par le compilateur constitue un automate à état qui comporte quatre états:</p>
<ul>
<li>l&#8217;état -2 indique que l&#8217;automate est invalide,</li>
<li>l&#8217;état 0 indique qu&#8217;il faut initialiser l&#8217;automate,</li>
<li>l&#8217;état 1 indique qu&#8217;il est initialisé et que l&#8217;on peut continuer le traitement,</li>
<li>l&#8217;état -1 indique que l&#8217;automate est en cours d&#8217;initialisation.</li>
</ul>
<p>La méthode MoveNext contient le traitement qui permet de générer les éléments. La méthode GetEnumerator retourne un énumérateur dont l&#8217;automate se retrouve dans l&#8217;état initial. Etant donné que la méthode Reset n&#8217;est plus supportée, GetEnumerator retourne à chaque fois une nouvelle instance initialisé dans l&#8217;état 0 (indique le début de l&#8217;itération).</p>
<h3>Bilan général</h3>
<p>Nous avons vu qu&#8217;il devient très facile d&#8217;écrire des itérateurs grâce au mot-clef yield. Vous savez désormais que le compilateur génère une classe interne à notre implémentation qui permet de gérer un automate à états qui s&#8217;occupe de lister les éléments pendant les itérations. Il est important de noter que l&#8217;automate peut devenir complexe en fonction de votre traitement. Il ne faut pas non plus oublier que chaque boucle foreach va demander au runtime une nouvelle instance de la classe d&#8217;itération. Il faudra donc veiller à la consommation mémoire.</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.pascallacroix.net/blog/2006/10/25/introduction-aux-iterateurs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
