<?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/ja/tags/dotnet-11/</link><description>Articles, tutorials and insights from the .NET community.</description><generator>Hugo</generator><language>ja</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/ja/tags/dotnet-11/index.xml" rel="self" type="application/rss+xml"/><item><title>ピンクラスタリングがついに .NET MAUI Maps に登場 — プロパティ1つ、手間ゼロ</title><link>https://thedotnetblog.com/ja/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/ja/news/emiliano-montesdeoca/maui-maps-pin-clustering-finally/</guid><description>.NET MAUI 11 Preview 3 で Map コントロールにネイティブなピンクラスタリングが追加されました。プロパティ1つ、独立したクラスタリンググループ、タップ処理 — すべて組み込み。</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;この記事は自動翻訳されています。原文は&lt;a href="https://thedotnetblog.com/ja/news/emiliano-montesdeoca/maui-maps-pin-clustering-finally/"&gt;こちら&lt;/a&gt;をご覧ください。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;マップに100個のピンを読み込んだら、全体が読めない塊になった — そんな経験ありませんか？そう、これまでの .NET MAUI Maps はまさにそんな感じでした。もう終わりです。&lt;/p&gt;
&lt;p&gt;David Ortinau が&lt;a href="https://devblogs.microsoft.com/dotnet/pin-clustering-in-dotnet-maui-maps/"&gt;発表しました&lt;/a&gt;。.NET MAUI 11 Preview 3 では、Android と iOS/Mac Catalyst でピンクラスタリングがすぐに使える状態で搭載されています。そして最高なのは — 有効にするのが驚くほど簡単だということです。&lt;/p&gt;
&lt;h2 id="すべてを支配する1つのプロパティ"&gt;すべてを支配する1つのプロパティ&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;これだけです。近くのピンがカウントバッジ付きのクラスターにグループ化されます。ズームインすると展開。ズームアウトすると折りたたみ。モダンなマップならどれでも期待される動作 — それがたった1つのプロパティで手に入ります。&lt;/p&gt;
&lt;h2 id="独立したクラスタリンググループ"&gt;独立したクラスタリンググループ&lt;/h2&gt;
&lt;p&gt;ここからが面白いところです。すべてのピンが一緒にクラスタリングされるべきではありません。コーヒーショップと公園は別物で、マップもそれを知っているべきです。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ClusteringIdentifier&lt;/code&gt; プロパティを使えば、ピンを独立したグループに分けられます：&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;同じ識別子を持つピンは一緒にクラスタリングされます。異なる識別子は、地理的に近くても独立したクラスターを形成します。識別子なし？デフォルトグループです。シンプルで予測可能。&lt;/p&gt;
&lt;h2 id="クラスタータップの処理"&gt;クラスタータップの処理&lt;/h2&gt;
&lt;p&gt;ユーザーがクラスターをタップすると、必要なものがすべて揃った &lt;code&gt;ClusterClicked&lt;/code&gt; イベントを受け取ります：&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;イベント引数には &lt;code&gt;Pins&lt;/code&gt;（クラスター内のピン）、&lt;code&gt;Location&lt;/code&gt;（地理的中心）、&lt;code&gt;Handled&lt;/code&gt;（デフォルトのズーム動作をオーバーライドしたい場合は &lt;code&gt;true&lt;/code&gt; に設定）が含まれます。シンプルで実用的、まさに期待通り。&lt;/p&gt;
&lt;h2 id="知っておくべきプラットフォームの詳細"&gt;知っておくべきプラットフォームの詳細&lt;/h2&gt;
&lt;p&gt;Android では、クラスタリングはズーム変更時に再計算するカスタムのグリッドベースアルゴリズムを使用します — 外部依存なし。iOS と Mac Catalyst では、MapKit のネイティブ &lt;code&gt;MKClusterAnnotation&lt;/code&gt; サポートを活用しており、スムーズでプラットフォームネイティブなアニメーションを実現しています。&lt;/p&gt;
&lt;p&gt;これは MAUI チームが正しい判断をしたケースの1つです — プラットフォームの力を活かすべきところで活かす。&lt;/p&gt;
&lt;h2 id="なぜこれが重要なのか"&gt;なぜこれが重要なのか&lt;/h2&gt;
&lt;p&gt;ピンクラスタリングは .NET MAUI で最もリクエストの多かった機能の1つです（&lt;a href="https://github.com/dotnet/maui/issues/11811"&gt;issue #11811&lt;/a&gt;）。それも当然です。マップ上に場所を表示するすべてのアプリ — 配送追跡、店舗検索、不動産 — に必要です。以前は自分で実装するか、サードパーティライブラリを使う必要がありました。今は組み込みです。&lt;/p&gt;
&lt;p&gt;クロスプラットフォームモバイルアプリを構築する .NET 開発者にとって、これはまさに MAUI をマップ中心のシナリオで実用的な選択肢にする生活の質の向上です。&lt;/p&gt;
&lt;h2 id="始めよう"&gt;始めよう&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://dotnet.microsoft.com/download/dotnet/11.0"&gt;.NET 11 Preview 3&lt;/a&gt; をインストールして .NET MAUI ワークロードを更新してください。&lt;a href="https://github.com/dotnet/maui-samples/tree/main/10.0/UserInterface/Views/Map/MapDemo/WorkingWithMaps"&gt;Maps サンプル&lt;/a&gt;には新しいクラスタリングページが含まれており、すぐに試すことができます。&lt;/p&gt;
&lt;p&gt;何か作ってみてください — そしてマップにやっと余裕を持たせましょう。&lt;/p&gt;</content:encoded></item><item><title>C# 15にユニオン型が登場 — まさに私たちが求めていたもの</title><link>https://thedotnetblog.com/ja/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/ja/news/emiliano-montesdeoca/csharp-15-union-types-exhaustive-matching/</guid><description>C# 15がunionキーワードを導入 — コンパイラが強制する判別共用体と網羅的パターンマッチング。その見た目、重要な理由、そして今日試す方法を紹介します。</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;この記事は自動翻訳されています。原文は&lt;a href="https://thedotnetblog.com/ja/news/emiliano-montesdeoca/csharp-15-union-types-exhaustive-matching/"&gt;こちら&lt;/a&gt;をご覧ください。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;これこそ待ち望んでいたものです。C# 15が&lt;code&gt;union&lt;/code&gt;キーワードを導入しました — コンパイラが強制する網羅的パターンマッチングを備えた本格的な判別共用体です。F#の判別共用体やRustのenumを羨ましく思ったことがあるなら、これがなぜ重要かすぐにわかるでしょう。&lt;/p&gt;
&lt;p&gt;Bill Wagnerが.NETブログで&lt;a href="https://devblogs.microsoft.com/dotnet/csharp-15-union-types/"&gt;詳細な解説を公開しました&lt;/a&gt;。正直なところ、設計はクリーンで実用的、そしてとてもC#らしいです。実際に何があるのか、そしてなぜ一見した印象以上に大きな意味があるのかを見ていきましょう。&lt;/p&gt;
&lt;h2 id="ユニオンが解決する問題"&gt;ユニオンが解決する問題&lt;/h2&gt;
&lt;p&gt;C# 15以前では、メソッドから「複数の可能な型のうちの1つ」を返すことは常に妥協の産物でした：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;object&lt;/code&gt;&lt;/strong&gt; — 制約なし、コンパイラの助けなし、あらゆるところで防御的キャスト&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;マーカーインターフェース&lt;/strong&gt; — より良いが、誰でも実装できる。コンパイラはセットが完全だと判断できない&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;抽象基底クラス&lt;/strong&gt; — 同じ問題、さらに型に共通の祖先が必要&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらのどれも本当に欲しいものを提供してくれません：コンパイラがすべてのケースを処理したことを保証する閉じた型のセット。ユニオン型がそれを実現します。&lt;/p&gt;
&lt;h2 id="構文は美しくシンプル"&gt;構文は美しくシンプル&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;1行だけ。&lt;code&gt;Pet&lt;/code&gt;は&lt;code&gt;Cat&lt;/code&gt;、&lt;code&gt;Dog&lt;/code&gt;、または&lt;code&gt;Bird&lt;/code&gt;を保持できます。暗黙的な変換は自動的に生成されます：&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;そしてここが魔法です — コンパイラが網羅的マッチングを強制します：&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;ディスカード&lt;code&gt;_&lt;/code&gt;は不要です。コンパイラはこのswitchがすべての可能なケースをカバーしていることを知っています。後から4番目の型をユニオンに追加すると、それを処理しないすべてのswitch式が警告を生成します。不足しているケースがランタイムではなくビルド時にキャッチされます。&lt;/p&gt;
&lt;h2 id="実用的になるところ"&gt;実用的になるところ&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Pet&lt;/code&gt;の例はかわいいですが、ここからがユニオンが本当のコードで輝くところです。&lt;/p&gt;
&lt;h3 id="異なる形状を返すapiレスポンス"&gt;異なる形状を返すAPIレスポンス&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;これですべてのコンシューマは成功、エラー、バリデーション失敗を処理することを強制されます。「エラーケースのチェックを忘れた」バグはもうありません。&lt;/p&gt;
&lt;h3 id="単一値またはコレクション"&gt;単一値またはコレクション&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;OneOrMore&amp;lt;T&amp;gt;&lt;/code&gt;パターンは、ユニオンがヘルパーメソッドを持つボディを持てることを示しています：&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;呼び出し側は便利な方の形式を渡します：&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="無関係な型の合成"&gt;無関係な型の合成&lt;/h3&gt;
&lt;p&gt;これは従来の階層に対するキラー機能です。共通点のない型をユニオンにできます — &lt;code&gt;string&lt;/code&gt;と&lt;code&gt;Exception&lt;/code&gt;、&lt;code&gt;int&lt;/code&gt;と&lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;。共通の祖先は不要です。&lt;/p&gt;
&lt;h2 id="既存ライブラリ用のカスタムユニオン"&gt;既存ライブラリ用のカスタムユニオン&lt;/h2&gt;
&lt;p&gt;ここにはスマートな設計判断があります：基本パターン（ケース型のパブリックコンストラクタと&lt;code&gt;Value&lt;/code&gt;プロパティ）に従っている限り、&lt;code&gt;[Union]&lt;/code&gt;属性を持つ任意のクラスやstructがユニオン型として認識されます。すでにユニオンライクな型を提供しているOneOfのようなライブラリは、内部を書き直すことなくコンパイラサポートにオプトインできます。&lt;/p&gt;
&lt;p&gt;値型を使うパフォーマンスに敏感なシナリオでは、ライブラリは&lt;code&gt;HasValue&lt;/code&gt;と&lt;code&gt;TryGetValue&lt;/code&gt;メソッドによるボックス化なしのアクセスパターンを実装できます。&lt;/p&gt;
&lt;h2 id="より大きな視点"&gt;より大きな視点&lt;/h2&gt;
&lt;p&gt;ユニオン型はC#に来るより広い網羅性ストーリーの一部です：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ユニオン型&lt;/strong&gt; — 閉じた型セットに対する網羅的マッチング（プレビューで利用可能）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;閉じた階層&lt;/strong&gt; — &lt;code&gt;closed&lt;/code&gt;修飾子が定義アセンブリ外の派生クラスを防止（提案中）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;閉じたenum&lt;/strong&gt; — 宣言されたメンバー以外の値の作成を防止（提案中）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これら3つの機能が合わさることで、C#はあらゆるメインストリーム言語の中で最も包括的な型安全パターンマッチングシステムの1つを手に入れることになります。&lt;/p&gt;
&lt;h2 id="今日試してみよう"&gt;今日試してみよう&lt;/h2&gt;
&lt;p&gt;ユニオン型は.NET 11 Preview 2で利用可能です：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dotnet.microsoft.com/download/dotnet"&gt;.NET 11 Preview SDK&lt;/a&gt;をインストール&lt;/li&gt;
&lt;li&gt;プロジェクトで&lt;code&gt;net11.0&lt;/code&gt;をターゲットに設定&lt;/li&gt;
&lt;li&gt;&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;1つ注意点：Preview 2では、ランタイムにまだ含まれていないため、プロジェクトで&lt;code&gt;UnionAttribute&lt;/code&gt;と&lt;code&gt;IUnion&lt;/code&gt;を宣言する必要があります。docsリポジトリから&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;を取得するか、以下を追加してください：&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="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;p&gt;ユニオン型は、それなしでどうやってきたのか不思議に思わせる機能の1つです。コンパイラが強制する網羅的マッチング、クリーンな構文、ジェネリックサポート、既存のパターンマッチングとの統合 — 私たちが求めていたすべてが、C#のやり方で実現されています。&lt;/p&gt;
&lt;p&gt;.NET 11 Preview 2で試して、壊して、&lt;a href="https://github.com/dotnet/csharplang/discussions/9663"&gt;GitHubでフィードバックを共有してください&lt;/a&gt;。これはプレビューであり、C#チームは積極的に耳を傾けています。あなたのエッジケースとデザインフィードバックが最終リリースを形作ります。&lt;/p&gt;
&lt;p&gt;完全な言語リファレンスについては、&lt;a href="https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/union"&gt;ユニオン型のドキュメント&lt;/a&gt;と&lt;a href="https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/unions"&gt;機能仕様&lt;/a&gt;をご覧ください。&lt;/p&gt;</content:encoded></item></channel></rss>