<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Dotnet-11 | The .NET Blog</title><link>https://thedotnetblog.com/fr/tags/dotnet-11/</link><description>Articles, tutorials and insights from the .NET community.</description><generator>Hugo</generator><language>fr</language><managingEditor>@thedotnetblog (The .NET Blog)</managingEditor><webMaster>@thedotnetblog</webMaster><lastBuildDate>Thu, 16 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://thedotnetblog.com/fr/tags/dotnet-11/index.xml" rel="self" type="application/rss+xml"/><item><title>Le clustering de pins arrive enfin dans .NET MAUI Maps — Une propriété, zéro prise de tête</title><link>https://thedotnetblog.com/fr/news/emiliano-montesdeoca/maui-maps-pin-clustering-finally/</link><pubDate>Thu, 16 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/fr/news/emiliano-montesdeoca/maui-maps-pin-clustering-finally/</guid><description>.NET MAUI 11 Preview 3 ajoute le clustering natif de pins au contrôle Map. Une propriété, des groupes de clustering séparés et la gestion des taps — tout est intégré.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Cet article a été traduit automatiquement. Pour la version originale, &lt;a href="https://thedotnetblog.com/fr/news/emiliano-montesdeoca/maui-maps-pin-clustering-finally/"&gt;cliquez ici&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Tu connais ce moment où tu charges une carte avec une centaine de pins et tout se transforme en une tache illisible ? Ouais, c&amp;rsquo;était ça l&amp;rsquo;expérience .NET MAUI Maps jusqu&amp;rsquo;à maintenant. C&amp;rsquo;est terminé.&lt;/p&gt;
&lt;p&gt;David Ortinau &lt;a href="https://devblogs.microsoft.com/dotnet/pin-clustering-in-dotnet-maui-maps/"&gt;vient d&amp;rsquo;annoncer&lt;/a&gt; que .NET MAUI 11 Preview 3 embarque le clustering de pins nativement sur Android et iOS/Mac Catalyst. Et le meilleur — c&amp;rsquo;est ridiculement simple à activer.&lt;/p&gt;
&lt;h2 id="une-propriété-pour-les-gouverner-tous"&gt;Une propriété pour les gouverner tous&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;maps:Map&lt;/span&gt; &lt;span class="na"&gt;IsClusteringEnabled=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;True&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;C&amp;rsquo;est tout. Les pins proches sont regroupés en clusters avec un badge de comptage. Zoom avant, ils s&amp;rsquo;expandent. Zoom arrière, ils se regroupent. Le genre de comportement que les utilisateurs attendent de n&amp;rsquo;importe quelle carte moderne — et maintenant tu l&amp;rsquo;obtiens avec une seule propriété.&lt;/p&gt;
&lt;h2 id="groupes-de-clustering-indépendants"&gt;Groupes de clustering indépendants&lt;/h2&gt;
&lt;p&gt;C&amp;rsquo;est là que ça devient intéressant. Tous les pins ne devraient pas se regrouper ensemble. Les cafés et les parcs sont des choses différentes, et ta carte devrait le savoir.&lt;/p&gt;
&lt;p&gt;La propriété &lt;code&gt;ClusteringIdentifier&lt;/code&gt; te permet de séparer les pins en groupes indépendants :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Pin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Label&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Pike Place Coffee&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;47.6097&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="m"&gt;122.3331&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ClusteringIdentifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;coffee&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Pin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Label&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Occidental Square&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;47.6064&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="m"&gt;122.3325&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ClusteringIdentifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;parks&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Les pins avec le même identifiant se regroupent ensemble. Des identifiants différents forment des clusters indépendants même quand ils sont géographiquement proches. Pas d&amp;rsquo;identifiant ? Groupe par défaut. Propre et prévisible.&lt;/p&gt;
&lt;h2 id="gestion-des-taps-sur-les-clusters"&gt;Gestion des taps sur les clusters&lt;/h2&gt;
&lt;p&gt;Quand un utilisateur tape sur un cluster, tu reçois un événement &lt;code&gt;ClusterClicked&lt;/code&gt; avec tout ce dont tu as besoin :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClusterClicked&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Label&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;DisplayAlert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;$&amp;#34;Cluster ({e.Pins.Count} pins)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;OK&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Suppress default zoom-to-cluster behavior:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// e.Handled = true;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Les arguments de l&amp;rsquo;événement te donnent &lt;code&gt;Pins&lt;/code&gt; (les pins du cluster), &lt;code&gt;Location&lt;/code&gt; (le centre géographique) et &lt;code&gt;Handled&lt;/code&gt; (à mettre sur &lt;code&gt;true&lt;/code&gt; si tu veux surcharger le zoom par défaut). Simple, pratique, exactement ce qu&amp;rsquo;on attend.&lt;/p&gt;
&lt;h2 id="détails-de-plateforme-à-connaître"&gt;Détails de plateforme à connaître&lt;/h2&gt;
&lt;p&gt;Sur Android, le clustering utilise un algorithme personnalisé basé sur une grille qui recalcule lors des changements de zoom — aucune dépendance externe. Sur iOS et Mac Catalyst, il exploite le support natif de &lt;code&gt;MKClusterAnnotation&lt;/code&gt; de MapKit, ce qui signifie des animations fluides et natives de la plateforme.&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est un de ces cas où l&amp;rsquo;équipe MAUI a fait le bon choix — s&amp;rsquo;appuyer sur la plateforme là où ça a du sens.&lt;/p&gt;
&lt;h2 id="pourquoi-cest-important"&gt;Pourquoi c&amp;rsquo;est important&lt;/h2&gt;
&lt;p&gt;Le clustering de pins a été l&amp;rsquo;une des fonctionnalités les plus demandées dans .NET MAUI (&lt;a href="https://github.com/dotnet/maui/issues/11811"&gt;issue #11811&lt;/a&gt;), et pour une bonne raison. Chaque app qui affiche des emplacements sur une carte — suivi de livraisons, localisateurs de magasins, immobilier — en a besoin. Avant, il fallait le construire soi-même ou intégrer une bibliothèque tierce. Maintenant c&amp;rsquo;est intégré.&lt;/p&gt;
&lt;p&gt;Pour nous développeurs .NET qui construisons des apps mobiles multiplateformes, c&amp;rsquo;est exactement le type d&amp;rsquo;amélioration de qualité de vie qui fait de MAUI un choix véritablement pratique pour les scénarios lourds en cartes.&lt;/p&gt;
&lt;h2 id="pour-commencer"&gt;Pour commencer&lt;/h2&gt;
&lt;p&gt;Installe &lt;a href="https://dotnet.microsoft.com/download/dotnet/11.0"&gt;.NET 11 Preview 3&lt;/a&gt; et mets à jour le workload .NET MAUI. L&amp;rsquo;&lt;a href="https://github.com/dotnet/maui-samples/tree/main/10.0/UserInterface/Views/Map/MapDemo/WorkingWithMaps"&gt;exemple Maps&lt;/a&gt; inclut une nouvelle page Clustering avec laquelle tu peux jouer tout de suite.&lt;/p&gt;
&lt;p&gt;Va construire quelque chose avec — et laisse tes cartes enfin respirer.&lt;/p&gt;</content:encoded></item><item><title>C# 15 intègre les types union — et c'est exactement ce qu'on demandait</title><link>https://thedotnetblog.com/fr/news/emiliano-montesdeoca/csharp-15-union-types-exhaustive-matching/</link><pubDate>Sun, 05 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/fr/news/emiliano-montesdeoca/csharp-15-union-types-exhaustive-matching/</guid><description>C# 15 introduit le mot-clé union — des unions discriminées avec du pattern matching exhaustif imposé par le compilateur. Voici à quoi ça ressemble, pourquoi c'est important, et comment les essayer dès aujourd'hui.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Cet article a été traduit automatiquement. Pour la version originale, &lt;a href="https://thedotnetblog.com/fr/news/emiliano-montesdeoca/csharp-15-union-types-exhaustive-matching/"&gt;cliquez ici&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;C&amp;rsquo;est celle que j&amp;rsquo;attendais. C# 15 introduit le mot-clé &lt;code&gt;union&lt;/code&gt; — de vraies unions discriminées avec du pattern matching exhaustif imposé par le compilateur. Si vous avez déjà envié les unions discriminées de F# ou les enums de Rust, vous savez exactement pourquoi c&amp;rsquo;est important.&lt;/p&gt;
&lt;p&gt;Bill Wagner a &lt;a href="https://devblogs.microsoft.com/dotnet/csharp-15-union-types/"&gt;publié l&amp;rsquo;analyse approfondie&lt;/a&gt; sur le blog .NET, et franchement ? Le design est propre, pratique et très C#. Laissez-moi vous montrer ce qu&amp;rsquo;il y a vraiment et pourquoi c&amp;rsquo;est plus important qu&amp;rsquo;il n&amp;rsquo;y paraît à première vue.&lt;/p&gt;
&lt;h2 id="le-problème-que-les-unions-résolvent"&gt;Le problème que les unions résolvent&lt;/h2&gt;
&lt;p&gt;Avant C# 15, retourner &amp;ldquo;l&amp;rsquo;un des plusieurs types possibles&amp;rdquo; depuis une méthode était toujours un compromis :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;object&lt;/code&gt;&lt;/strong&gt; — pas de contraintes, pas d&amp;rsquo;aide du compilateur, du casting défensif partout&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interfaces marqueurs&lt;/strong&gt; — mieux, mais n&amp;rsquo;importe qui peut les implémenter. Le compilateur ne peut jamais considérer l&amp;rsquo;ensemble comme complet&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Classes de base abstraites&lt;/strong&gt; — même problème, en plus les types ont besoin d&amp;rsquo;un ancêtre commun&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Aucune de ces solutions ne vous donne ce que vous voulez vraiment : un ensemble fermé de types où le compilateur garantit que vous avez géré chaque cas. C&amp;rsquo;est ce que font les types union.&lt;/p&gt;
&lt;h2 id="la-syntaxe-est-dune-simplicité-élégante"&gt;La syntaxe est d&amp;rsquo;une simplicité élégante&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;class&lt;/span&gt; &lt;span class="n"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;class&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;class&lt;/span&gt; &lt;span class="n"&gt;Bird&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;union&lt;/span&gt; &lt;span class="n"&gt;Pet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Bird&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Une ligne. &lt;code&gt;Pet&lt;/code&gt; peut contenir un &lt;code&gt;Cat&lt;/code&gt;, un &lt;code&gt;Dog&lt;/code&gt; ou un &lt;code&gt;Bird&lt;/code&gt;. Les conversions implicites sont générées automatiquement :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Pet&lt;/span&gt; &lt;span class="n"&gt;pet&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Rex&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Dog { Name = Rex }&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Et voici la magie — le compilateur impose le matching exhaustif :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pet&lt;/span&gt; &lt;span class="k"&gt;switch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Dog&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Cat&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Bird&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pas besoin de discard &lt;code&gt;_&lt;/code&gt;. Le compilateur sait que ce switch couvre tous les cas possibles. Si vous ajoutez plus tard un quatrième type à l&amp;rsquo;union, chaque expression switch qui ne le gère pas produit un avertissement. Les cas manquants détectés au moment de la compilation, pas à l&amp;rsquo;exécution.&lt;/p&gt;
&lt;h2 id="là-où-ça-devient-pratique"&gt;Là où ça devient pratique&lt;/h2&gt;
&lt;p&gt;L&amp;rsquo;exemple de &lt;code&gt;Pet&lt;/code&gt; est mignon, mais c&amp;rsquo;est ici que les unions brillent vraiment dans du vrai code.&lt;/p&gt;
&lt;h3 id="des-réponses-api-qui-retournent-différentes-formes"&gt;Des réponses API qui retournent différentes formes&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;union&lt;/span&gt; &lt;span class="n"&gt;ApiResult&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ApiError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ValidationFailure&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Maintenant chaque consommateur est obligé de gérer le succès, l&amp;rsquo;erreur et l&amp;rsquo;échec de validation. Plus de bugs &amp;ldquo;j&amp;rsquo;ai oublié de vérifier le cas d&amp;rsquo;erreur&amp;rdquo;.&lt;/p&gt;
&lt;h3 id="valeur-unique-ou-collection"&gt;Valeur unique ou collection&lt;/h3&gt;
&lt;p&gt;Le pattern &lt;code&gt;OneOrMore&amp;lt;T&amp;gt;&lt;/code&gt; montre comment les unions peuvent avoir un corps avec des méthodes utilitaires :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;union&lt;/span&gt; &lt;span class="n"&gt;OneOrMore&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;AsEnumerable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="k"&gt;switch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;single&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;single&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;multiple&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;multiple&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Les appelants passent la forme qui leur convient :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;OneOrMore&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;dotnet&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;OneOrMore&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;moreTags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;csharp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;unions&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;preview&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsEnumerable&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;[{tag}] &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// [dotnet]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="composer-des-types-sans-relation"&gt;Composer des types sans relation&lt;/h3&gt;
&lt;p&gt;C&amp;rsquo;est la fonctionnalité décisive par rapport aux hiérarchies traditionnelles. Vous pouvez unir des types qui n&amp;rsquo;ont rien en commun — &lt;code&gt;string&lt;/code&gt; et &lt;code&gt;Exception&lt;/code&gt;, &lt;code&gt;int&lt;/code&gt; et &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;. Pas besoin d&amp;rsquo;ancêtre commun.&lt;/p&gt;
&lt;h2 id="unions-personnalisées-pour-les-bibliothèques-existantes"&gt;Unions personnalisées pour les bibliothèques existantes&lt;/h2&gt;
&lt;p&gt;Voici un choix de design intelligent : toute classe ou struct avec un attribut &lt;code&gt;[Union]&lt;/code&gt; est reconnue comme un type union, tant qu&amp;rsquo;elle suit le pattern de base (constructeurs publics pour les types de cas et une propriété &lt;code&gt;Value&lt;/code&gt;). Les bibliothèques comme OneOf qui fournissent déjà des types similaires aux unions peuvent opter pour le support du compilateur sans réécrire leurs internals.&lt;/p&gt;
&lt;p&gt;Pour les scénarios sensibles à la performance avec des types valeur, les bibliothèques peuvent implémenter un pattern d&amp;rsquo;accès sans boxing avec les méthodes &lt;code&gt;HasValue&lt;/code&gt; et &lt;code&gt;TryGetValue&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="la-vision-densemble"&gt;La vision d&amp;rsquo;ensemble&lt;/h2&gt;
&lt;p&gt;Les types union font partie d&amp;rsquo;une histoire plus large d&amp;rsquo;exhaustivité qui arrive en C# :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Types union&lt;/strong&gt; — matching exhaustif sur un ensemble fermé de types (disponible maintenant en preview)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hiérarchies fermées&lt;/strong&gt; — le modificateur &lt;code&gt;closed&lt;/code&gt; empêche les classes dérivées en dehors de l&amp;rsquo;assembly de définition (proposé)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enums fermés&lt;/strong&gt; — empêche la création de valeurs autres que les membres déclarés (proposé)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ensemble, ces trois fonctionnalités donneront à C# l&amp;rsquo;un des systèmes de pattern matching typé les plus complets de tous les langages mainstream.&lt;/p&gt;
&lt;h2 id="essayez-les-aujourdhui"&gt;Essayez-les aujourd&amp;rsquo;hui&lt;/h2&gt;
&lt;p&gt;Les types union sont disponibles dans .NET 11 Preview 2 :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Installez le &lt;a href="https://dotnet.microsoft.com/download/dotnet"&gt;SDK .NET 11 Preview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ciblez &lt;code&gt;net11.0&lt;/code&gt; dans votre projet&lt;/li&gt;
&lt;li&gt;Définissez &lt;code&gt;&amp;lt;LangVersion&amp;gt;preview&amp;lt;/LangVersion&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Une mise en garde : dans Preview 2, vous devrez déclarer &lt;code&gt;UnionAttribute&lt;/code&gt; et &lt;code&gt;IUnion&lt;/code&gt; dans votre projet car ils ne sont pas encore dans le runtime. Récupérez &lt;a href="https://github.com/dotnet/docs/blob/e68b5dd1e557b53c45ca43e61b013bc919619fb9/docs/csharp/language-reference/builtin-types/snippets/unions/RuntimePolyfill.cs"&gt;RuntimePolyfill.cs&lt;/a&gt; depuis le repo docs, ou ajoutez ceci :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;System.Runtime.CompilerServices&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; AllowMultiple = false)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UnionAttribute&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Attribute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IUnion&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;object?&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="pour-conclure"&gt;Pour conclure&lt;/h2&gt;
&lt;p&gt;Les types union sont une de ces fonctionnalités qui vous font vous demander comment on a pu s&amp;rsquo;en passer. Du matching exhaustif imposé par le compilateur, une syntaxe propre, le support des génériques et l&amp;rsquo;intégration avec le pattern matching existant — c&amp;rsquo;est tout ce qu&amp;rsquo;on demandait, fait à la manière C#.&lt;/p&gt;
&lt;p&gt;Essayez-les dans .NET 11 Preview 2, cassez des trucs et &lt;a href="https://github.com/dotnet/csharplang/discussions/9663"&gt;partagez vos retours sur GitHub&lt;/a&gt;. C&amp;rsquo;est une preview, et l&amp;rsquo;équipe C# écoute activement. Vos cas limites et retours de design façonneront la version finale.&lt;/p&gt;
&lt;p&gt;Pour la référence complète du langage, consultez la &lt;a href="https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/union"&gt;documentation des types union&lt;/a&gt; et la &lt;a href="https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/unions"&gt;spécification de la fonctionnalité&lt;/a&gt;.&lt;/p&gt;</content:encoded></item></channel></rss>