個人的なメモ

Tomohiro Suzuki @hiro128_777 のブログです。Xamarin に関する事を中心に書いています。 Microsoft MVP for Development Technologies 2017- 本ブログと所属組織の公式見解は関係ございません。

C# 10 の新機能 - レコード構造体

C# 10 の新機能の情報の目次は以下をご覧ください。
hiro128.hatenablog.jp 
 

 

レコード構造体

C# 9 でレコードクラスが追加されましたが、C# 10 ではレコード構造体が追加されました。
C# 10 ではレコード構造体が追加されたことで、クラスより速度が出る構造体でレコード型を利用可能になりました。
 

導入の意図

レコード型(レコード構造体、レコードクラス)は、簡潔なコードで便利にデータを格納するための型です。

通常のクラスや構造体でデータモデルを作成しようとすると、データとしての等価性をサポートするための Equals のオーバーライドや operator == のオーバーロード、データ表示用の書式設定のための ToString のオーバーライドやデータを不変にするための構文など面倒な手間が生じます。

レコード型を利用すると、不変なプロパティを持つ型を簡潔な構文で作成でき、データ指向の型に役立つ動作が組み込みでサポートされているので、データモデルを簡潔に定義できます。
 

値の等価性

レコード構造体(レコードクラスも含む)は等価性に特徴があります。

  • record class 型の場合、型が同じで同じ値が格納されていれば、2 つのオブジェクトは等しい。
  • record struct 型の場合、型が同じで同じ値が格納されていれば、2 つのオブジェクトは等しい。

比較として、レコード型ではないクラスや構造体の等価性は以下の通りです。

  • class 型の場合、メモリ内の同じオブジェクトを参照していれば、2 つのオブジェクトは等しい。
  • struct 型の場合、型が同じで同じ値が格納されていれば、2 つのオブジェクトは等しい。

 

コード
// レコード構造体
PersonStruct person01 = new("太郎", "山田", new DateOnly(1990, 4, 15));
PersonStruct person02 = new("太郎", "山田", new DateOnly(1990, 4, 15));

Console.WriteLine("レコード構造体");
Console.WriteLine(person01 == person02);


// レコードクラス
PersonClass person03 = new("太郎", "山田", new DateOnly(1990, 4, 15));
PersonClass person04 = new("太郎", "山田", new DateOnly(1990, 4, 15));

Console.WriteLine("レコードクラス");
Console.WriteLine(person03 == person04);

record struct PersonStruct(string FirstName, string LastName, DateOnly Birthday);
record class PersonClass(string FirstName, string LastName, DateOnly Birthday);

 

実行結果
レコード構造体
True
-----------
レコードクラス
True

 

表示用の組み込みの書式設定

レコード型では既定で ToString メソッドで、パブリック プロパティとフィールドの名前と値が表示されます。
これは、データを取り扱う型としてはとても便利です。

<record type name> { <property name> = <value>, <property name> = <value>, ...}

 

コード
PersonStruct person01 = new("太郎", "山田", new DateOnly(1990, 4, 15));
Console.WriteLine(person01);

record struct PersonStruct(string FirstName, string LastName, DateOnly Birthday);

 

実行結果
PersonStruct { FirstName = 太郎, LastName = 山田, Birthday = 4/15/1990 }

 

with 式

with 式を使うと、元のインスタンスの値はそのままに、指定したプロパティとフィールドが変更された、コピーを作成できます。
膨大なプロパティを持つレコード型の一部のプロパティだけを変更したコピーを簡潔な構文で作成できるので非常に便利です。

補足ですが、C#10 以降ではレコード型ではない、struct 型も with 式 をサポートしています。
 

コード
PersonStruct person01 = new("太郎", "山田", new DateOnly(1990, 4, 15));
PersonStruct person02 = new("太郎", "山田", new DateOnly(1990, 4, 15));

person02 = person01 with { FirstName = "花子" };
Console.WriteLine(person02);
Console.WriteLine(person01 == person02);

record struct PersonStruct(string FirstName, string LastName, DateOnly Birthday);

 

実行結果
PersonStruct { FirstName = 花子, LastName = 山田, Birthday = 4/15/1990 }
False

 
なお、レコード構造体はC# 9 のクラスベースのレコードと似ていますが、重要な違いがあります。

  • レコード構造体のプロパティは、デフォルトで変更可能(get / set)です。
  • レコードクラスのプロパティは、デフォルトでは不変(get / init)です

初期化後に init キーワードが設定されているプロパティを再割り当てしようとすると、コンパイルエラーが発生します。
※readonly キーワードを追加することでレコード構造体を不変にできます。

レコード構造体はレコード クラスに取って代わるものではなく、レコード クラスからレコード構造体への移行を推奨するものではありませんので、クラスと構造体のどちらのレコードを使用するかは、利用シナリオに合わせ選択する必要があります。
 
公式情報:
Record structs
レコード (C# リファレンス)
 
 

C# 10 の新機能

C# 10 の新機能

C# 10 の新機能の特長は、「簡潔なコードを書くための機能」が多く追加されていることです。
新しい機能を利用することでお作法的なコードを排除でき、簡潔で直感的なコードを記述できるのでぜひ確認してみてください。

C# 10 の新機能については以下の公式情報にまとめられています。
docs.microsoft.com
 
.NET 6 の新機能の情報は以下をご覧ください。
hiro128.hatenablog.jp
 

 

レコード構造体

レコード構造体については以下の記事を参照ください。
hiro128.hatenablog.jp
 

global using

global using については以下の記事を参照ください。
hiro128.hatenablog.jp
 

暗黙的な using ディレクティブ

暗黙的な using ディレクティブについては以下の記事を参照ください。
hiro128.hatenablog.jp
 

ファイルスコープの名前空間宣言

ファイルスコープの名前空間宣言については以下の記事を参照ください。
hiro128.hatenablog.jp
  

ラムダ式の自然型

ラムダ式の自然型については以下の記事を参照ください。
hiro128.hatenablog.jp
 

const および文字列補間

const および文字列補間については以下の記事を参照ください。
hiro128.hatenablog.jp
 

拡張プロパティパターン

拡張プロパティパターンについては以下の記事を参照ください。
hiro128.hatenablog.jp

 
  

ASP.NET Core Update(.NET 6)の整理(随時更新中)

.NET 6 の RC 2 がリリースされました。ASP.NET Core についても Preview 1 から RC 2 まで段階的に情報や新機能がリリースされており、情報が分散して探しにくいので重要な更新情報を整理してみました。
  
公式情報も更新されているため、内容は随時更新中です。
 
.NET 6 の更新情報は以下をご覧ください。
hiro128.hatenablog.jp
 
 

 
 

Minimal API の導入(.NET 6 Preview 4)

公式情報:
Introducing minimal APIs
関連記事:
hiro128.hatenablog.jp
 

Minimal API のアップデート(.NET 6 RC 2)

Minimal API に対し、以下のいくつかのアップデートがあります。
公式情報:Minimal API updates
 

パラメータのバインディングの対応強化(.NET 6 RC 2)

  • TryParseBindAsync に継承されたメソッドに対するサポートを追加
  • パブリックの TryParseBindAsync メソッドが正しい形式かどうかをチェックする機能が追加
  • これらのメソッドに間違った構文を使っている場合エラーがスローされるようになった
  • カスタムタイプにルート、ヘッダ属性、およびクエリ文字列から値をバインドしたい場合、カスタムタイプに静的な TryParse メソッドを追加することができる

公式情報:Parameter Binding
 

OpenAPI の対応強化(.NET 6 RC 2)

  • Accepts() 拡張メソッドや [Consumes(typeof(Todo), "application/json", IsRequired = false)] 属性を使って、リクエストボディが必須かどうかを記述できる
  • Accepts 拡張メソッドとConsumes 属性で、生成された open-api docs に対して、Todo タイプと application/json の両方を表現することができる。

公式情報:OpenAPI
 

ソースコードの分析(.NET 6 RC 2)
  • ルートハンドラの問題を素早く発見したり、ミドルウェアの設定ミスを警告したりするためのアナライザを追加
  • アナライザは、WebApplicationBuilderミドルウェアの順序を検証し、誤ったミドルウェアの構成や順序が検出された場合に警告する
  • IActionResult を実装した型がルートハンドラから返された場合に検出し、結果が意図せずに JSON としてシリアル化された場合に警告する機能を追加

公式情報:Source Code Analysis
 

APIの名前変更(破壊的変更)(.NET 6 RC 2)

  • 意図を適切に説明するために以下のAPIの名称を変更した。
    • DelegateEndpointConventionBuilder -> RouteHandlerBuilder
    • OpenApiDelegateEndpointConventionBuilderExtensions -> OpenApiRouteHandlerBuilderExtensions
    • DelegateEndpointRouteBuilderExtensions は、既存のEndpointRouteBuilderExtensions と統合した。

(上記の変更により、DelegateEndpointRouteHandlerに置き換え、クラス名のConventionを削除した)

公式情報:Breaking Changes (APIs Renames)
 

非同期ストリーミング(.NET 6 Preview 4)

  • コントローラのアクションからレスポンスのJSONフォーマッタに至るまで、非同期ストリーミングがサポートされるようになった
  • アクションからIAsyncEnumerableを返しても、レスポンスの内容が送信される前にメモリにバッファリングされなくなった
  • 非同期に列挙できる大規模なデータセットを返す際のメモリ使用量が削減される

公式情報:Async streaming
 

HTTP logging ミドルウェア(.NET 6 Preview 4)

  • HTTPリクエストとHTTPレスポンスの情報(ヘッダーとボディ全体を含む)を記録する、新しい組み込みミドルウェア
  • HTTP logging は以下のログを提供する
    • HTTP リクエスト情報
    • 共通のプロパティ
    • ヘッダー
    • ボディ
    • HTTP レスポンス情報

公式情報:HTTP logging middleware
 

.NET MAUI Update の整理(随時更新中)

.NET MAUI の Preview 9 がリリースされました。Preview 1 から Preview 9 まで段階的に情報や新機能がリリースされており、情報が分散して探しにくいので重要な更新情報を整理してみました。
  
公式情報も更新されているため、内容は随時更新中です。
 
.NET 6 の新機能の情報は以下をご覧ください。
hiro128.hatenablog.jp
 
 

  

.NET MAUI の GA の時期の遅延ついて(.NET MAUI Preview 8)

  • .NET MAUI の RC は2022年第1四半期に、GA は 2022年第2四半期の初めを目標とすることに延期された。
  • Xamarin は引き続き強化され、本番用のモバイルアプリの構築には Xamarin が推奨となる。
  • .NET MAUIで提供される予定のすべての機能は、.NET 6 がGAされる2021年11月にプレビューとして利用可能になる。
  • その後は、引き続き品質向上やユーザーからのフィードバックへの対応に取り組む。
  • .NET MAUIのプレビューは毎月リリースし続ける。

公式情報:Update on .NET Multi-platform App UI (.NET MAUI) - .NET Blog
 

Visual Studio 2022 との統合(.NET MAUI Preview 8 / Visual Studio 2022 Preview 4)

  • Visual Studio 2022 Preview 4 以降のインストール時に、「.NET によるモバイル開発」ワークロード内の.NET MAUI(プレビュー)をチェックできるようになり、.NET 6とオプションのワークロードの依存関係が導入されるようになった。

公式情報:Visual Studio 2022 Preview 4 Productivity
 

MAUI アプリの起動方法の更新(.NET MAUI Preview 8)

  • MAUI アプリの起動方法が更新され、各プラットフォームでは、MauiProgram.CreateMauiAppを呼び出すようになった。

公式情報:.NET MAUI SDK Updates
 

Android のアップデート(.NET MAUI Preview 8)

  • Android 向けにビルドされた .NET 6 アプリケーションでは、Android 12(API 31)がデフォルトになる。
  • Android 12 を使用するには、JDK 11 を手動でインストールする必要があるが、Visual StudioAndroid ツールが JDK 11 をサポートするまでの間、Android デザイナー、SDK マネージャー、デバイスマネージャーに好ましくない影響を与える可能性がある。
  • Visual StudioAndroidツール が JDK 11 を使用するように更新されたら、JDK 11 を .NET MAUI にデフォルトでバンドルする。
  • Androidプロジェクトでは、デフォルトで MaterialTheme が使用されるようになった。
  • これにより、Android でランタイムエラーが発生する場合は、Platforms/Android/MainActivity.cs で @style/Maui.SplashTheme が指定されていることを確認。
  • 更新された .NET MAUIテンプレートが参考になる。

公式情報:Android Updates
 

高速な Android のスタートアップ(.NET MAUI Preview 9)

  • Preview 9には、.NET MAUIのスタートアップトレースプロファイルが同梱されており、コマンドラインからビルドする際に使用することができる。
  • スタートアップトレースを活用して起動時の実行経路を追跡することで、アプリケーションの起動時に実行される部分のみを AOT 化し、スピードとサイズのバランスを取ることができる。

公式情報:Quick Android Startup
  

コントロールの更新(.NET MAUI Preview 9)

 

新しいレイアウト(.NET MAUI Preview 7)

  • 新しいレイアウトはデフォルトで有効になっている。
  • 新しいレイアウトは 7 年間の Xamarin.Forms のレイアウトから得た知見を採用した新しい LayoutManager アプローチに基づいて、一貫性、パフォーマンス、メンテナンス性が最適化されている。
  • 従来の Xamarin.Forms のレイアウトは、Xamarin.Formsからの移行プロジェクトとの互換性のために Microsoft.Maui.Controls.Compatibility 名前空間にのみ存在するようになった。

公式情報:New Layouts
 

新しいボーダーコントロール(.NET MAUI Preview 9)

  • 新しい Microsoft.Maui.Graphics ライブラリは、ネイティブのグラフィックスエンジンに基づいた一貫した UI 描画 API を提供する。
  • .NET MAUI のほとんどのレイアウトやコントロールに、ボーダー、コーナーレンダリング、美しいシャドウを簡単に追加できる。
  • 新しいボーダーコントロールは、任意のレイアウトやコントロールをラップして、ボーダーや各コーナーの独立した制御を追加することができる。

公式情報:Borders, Corners, and Shadows – Oh my!
 

アクセシビリティの変更と改善(.NET MAUI Preview 7)

TabIndex および IsTabStop の削除(.NET MAUI Preview 7)

  • TabIndex と IsTabStopプロパティは、開発者がスクリーンリーダーで読まれるUI要素の順序を制御するために Xamarin.Forms で導入されたが、実際には混乱を招きニーズを満たしていなかった。.
  • .NET MAUI では、インターフェイスの構造をプログラムで操作する方法を探すのではなく、読まれたいようにUIを順序付ける、巧みな設計アプローチを推奨している。
  • .NET MAUI で順番をコントロールしなければならない場合には、コミュニティツールキットの SemanticOrderView を推奨する。

公式情報:TabIndex and IsTabStop Removed
 

SetSemanticFocus とアナウンス(.NET MAUI Preview 7)

  • 新しい SemanticExtensions クラスの一部として、スクリーンリーダーのフォーカスを特定の要素に移動させることができるように、新しい SetSemanticFocus メソッドが追加された。

公式情報:SetSemanticFocus and Announce
 

フォントスケーリング(.NET MAUI Preview 7)

  • すべてのプラットフォームのすべてのコントロールで、フォント・スケーリングがデフォルトで有効になった。
  • これにより、OS 上でテキストスケーリングの設定を調整すると、その設定がアプリケーションの UI に反映され、デフォルトでよりアクセシブルなアプリケーションが実現する。

公式情報:Font Scaling
 

その他の注目すべき変更と追加

.NET MAUI Preview 8

公式情報:Other Changes

  • MinHeightRequest, MaxHeightRequest, MinWidthRequest, MaxWidthRequestに "Request "という接尾辞がなくなり、レイアウトシステムがそれらを真の値として扱うようになりなった。
  • 任意のコントロールマッパーにビヘイビアを追加する方法を簡素化- #1859
  • シェルテーマのスタイリングの様々な改善
  • Android #2027iOS #2029 用の RefreshView を追加
  • AbsoluteLayout を追加 #2136
  • Right-to-Left (RTL) FlowDirectionの追加 #948
  • Button.Icon ImageSourceを追加 #2079

.NET MAUI Preview 7

公式情報:Additional Highlights

  • Xamarin.Forms からアップグレードするプロジェクトをサポートする Effects のサポートの追加 #1574
  • AppThemeBinding の改良による、ダークテーマとライトテーマのモードのサポート #1657
  • ScrollView ハンドラ #1669
  • Android シェルのコアへの移植 #979
  • 複雑なオブジェクトを渡すシェルのナビゲーション #204
  • XAML ホットリロードのためのビジュアルツリーヘルパーの追加 #1845
  • System.ComponentModel.TypeConverterへの切り替え #1725
  • ウィンドウ ライフサイクル イベント #1754
  • ページナビゲーションイベント #1812
  • CSS プレフィックスを -maui に更新 #1877

 
 
以下、随時更新中です。

.NET 6 の Scatter/Gather IO の効果を Visual Studio for Mac 2022 Preview 1 on M1 Mac で試してみましたが、まだ、闇が深かったです(訂正済)

2021/10/05 22:40 検証方法に間違いがあったため(VS for Macデバッグありの実行になっていました)、再度検証し直し記事も訂正しております。ご指摘ありがとうございました。
 
 

はじめに

.NET 6 では FileStream がほぼ完全に書き直されており、速度と信頼性のが高まりました。また、複数のバッファーに対応した(Scatter / Gather IO)新しい API が導入されています。Scatter / Gather IO を使用すると、単一の sys-call で複数のバッファーを渡すことにより、高コストの sys-call の数を減らすことができます。
 
devblogs.microsoft.com
 
 

Visual Studio for Mac 2022 Preview 1 on M1 Mac で試したら...

WindowsLinux でのベンチマーク結果は公式ブログにデータがありましたので、Mac ではどのような結果になるか試してみました。
 
公式ブログの記事内のコードから、サンプルプロジェクトを作成しました。
github.com
 
ベンチマークのライブラリは、BenchmarkDotNet を利用しているようなので、同じように構成しました。
github.com
 
Visual Studio for Mac 2022 Preview 1 で実行した結果ですが...

// * Summary *

BenchmarkDotNet=v0.13.1, OS=macOS Big Sur 11.6 (20G165) [Darwin 20.6.0]
Apple M1 2.40GHz, 1 CPU, 8 logical and 8 physical cores
.NET SDK=6.0.100-rc.1.21463.6
  [Host]     : .NET 6.0.0 (6.0.21.45113), X64 RyuJIT
  DefaultJob : .NET 6.0.0 (6.0.21.45113), X64 RyuJIT


|      Method |     Mean |    Error |   StdDev |
|------------ |----------|----------|----------|
|       Write | 47.92 ms | 1.109 ms | 3.271 ms |
| WriteGather | 48.51 ms | 1.567 ms | 4.621 ms |

 
なんと上記の通り、WriteGather()の方が遅いという結果となりました...
 
 

ベクトル化 IO がうまく機能していない

詳細を解析していないのでなんとも言えないですが、公式ブログでは、Linux ではベクトル化 IO が機能しているとのことでしたが、Mac ではなんらかの理由でうまくベクトル化 IO が機能していない感じです。

一応、.NET 6 と Darwin のソースを調べてみましたが、pwritev() はサポートしているようですが、ベクトル化 IO がうまく機能していない詳細な原因まではわかりませんでした。
 
...と、いったんは思ったのですが、よく見ると、ベンチマーク結果が、X64 となっているので、Rosetta 2 による変換が入っているのが気になります。

ちなみに、意識せず x64 版がインストールされていたのは、dotnet-maui-check でインストールしたからでした。
 
 

Arm64 版 SDK をインストールして再度チャレンジ

というわけで、.NET 6 RC1 SDK をいったん全て削除して、再度 Arm64 版 SDK をインストールして Visual Studio for Mac 2022 Preview 1 で再度試したところ、今度は、無事成功しました。しかも、WriteGather()の方が速く、ベクトル化 IO も効果を発揮しています。

// * Summary *

BenchmarkDotNet=v0.13.1, OS=macOS Big Sur 11.6 (20G165) [Darwin 20.6.0]
Apple M1, 1 CPU, 8 logical and 8 physical cores
.NET SDK=6.0.100-rc.1.21463.6
  [Host]     : .NET 6.0.0 (6.0.21.45113), Arm64 RyuJIT
  DefaultJob : .NET 6.0.0 (6.0.21.45113), Arm64 RyuJIT


|      Method |     Mean |    Error |   StdDev |
|------------ |----------|----------|----------|
|       Write | 45.11 ms | 0.950 ms | 2.772 ms |
| WriteGather | 40.23 ms | 1.304 ms | 3.844 ms |

 
 

今回得た知見

今回の検証で以下のような知見を得ました。

  • M1 Mac .NET 6 の、Scatter/Gather IO は Arm64 版 でしか有効にならない。x64 版では効果がない。
  • M1 Mac .NET 6 SDK の、x64, Arm64 を両方インストールした場合、同じ場所に配置され、後にインストールした方が有効となる。side by side にはならない。
  • M1 Mac .NET 6 SDK の、x64, Arm64 を切り替えたい場合、念のため SDK をいったん削除してから再インストールした方が無難そう。
  • M1 MacVisual Studio for Mac 2022 Preview 1 では Arm64 版 SDK でのデバッグ実行がまだ正常動作しない。x64 版 SDK/Rosetta 2 ならデバッグ実行できる。

 
というわけで、Visual Studio for Mac 2022 の今後のリリースに期待します。
 
 
.NET 6 の更新情報は以下をご覧ください。
hiro128.hatenablog.jp

Visual Studio 2022 for Mac Preview 1 がリリースされましたので状況を確認してみました。

.NET 6 の GA まであと1ヶ月ちょっとのタイミングでようやく、Visual Studio 2022 for Mac Preview 1 がリリースされました。
devblogs.microsoft.com
 

UI が ネイティブの macOS UI で書き直されました。

これが Visual Studio 2022 for Mac の一番大きなトピックです。この件に工数がかかってしまい、他の件は手がまわりきらなかった感があります。見た目の違いは下記の通りです。色味が若干変わっており、視認性が良くなっています。
 
Xamarin の創設者 @migueldeicaza によると、Gtk+ から AppKit に書き直され C# / Xamarin.Mac で開発されているようです。


 

Visual Studio 2022 Visual Studio 2019
f:id:hiro128:20211003155331p:plain f:id:hiro128:20211003155724p:plain

 
その他、クラッシュの軽減とレスポンスが改善しているとのことです。

  • クラッシュの軽減については、長時間使用していないので体感できませんでした。
  • レスポンスの改善については、MacBook Air (M1, 2020) 上で大きな差ではないですが確かにもたつかなくなったという感覚はあります。

 
 

Windows 版に準じた Git の UI が適用されました

自分は、Git の操作はコマンドで行っているので、実際の画面を見てみてもよくわかりませんでしたが、Git のUI が Windows 版に近づいたそうです。確かにコードの変更箇所は見やすくなりました。
 
 

.NET 6 と C#10 への対応

例えば、Visual Studio 2019 for Mac では、.NET 6 RC1 を導入してもエラーが出てしまっていた以下の Minimal API のサンプルが動作するようになりました。
github.com
 

Visual Studio 2022 Visual Studio 2019
f:id:hiro128:20211003163745p:plain f:id:hiro128:20211003163809p:plain

 
 

SDK スタイルの Xamarin プロジェクトはまだ利用できません

下記のように、公式ブログに記載がある通り、SDK スタイルの iOS, Android プロジェクトはサポートされていません。.
 

Visual Studio for Mac continues to support web and cloud development with .NET Core 3.1 and later, mobile dev with Xamarin Traditional projects, and game development using Unity.

 
.NET 6 GA まであと1ヶ月強という状況と後述する MAUI の GA の情報から予想するに .NET 6 GA のタイミングでは、.NET 6 の iOS, Android のワークロードはサポートされず、これまでの非 SDK スタイルの従来の Xamarin.iOS, Xamarin.Android プロジェクトのサポートに留まる可能性が高そうですが、なんとかリリースされることを期待したい思いです。
 
なお、試しに既存の非 SDK スタイルの Xamarin.iOS プロジェクトを開いて、編集、デバッグしてみましたが、問題なく利用できました。
 
したがって、net6.0-android, net6.0-ios といった TFM が利用できるのも、もう少し先になりそうです。
 
 

.NET MAUI の GA は 2022 Q2 に延期されました。

2020年5月の公式ブログでは、以下のように

  • 2020年 Q4 から 2021年 Q3 までプレビュー
  • RC 2021年9月
  • GA 2021年11月

という予定でしたが 2022 Q2 延期になったようです。
devblogs.microsoft.com
 
 

まとめ

Preview 1 の状況をまとめると以下のような状況です。(実際に動作確認した結果です)

ワークロード 対応状況
コンソールアプリ
ASP.NET
Xamarin.iOS
Xamarin.Android
.NET 6 iOS
.NET 6 Android
.NET 6 Mac Catalyst
MAUI

 
まだ Preview 1 ですのでこれから新たな機能がリリースされると思います。次のプレビューを期待して待ちます。

.NET 6 Preview 4 以降で ASP.NET Core プロジェクトを作成するとデフォルトの起動プロファイルが Kestrel になります

.NET 6 Preview 4 以降で ASP.NET Core プロジェクトを作成するとデフォルトの起動プロファイルが Kestrel になります。
devblogs.microsoft.com
 
 
以下のように、デフォルトの起動プロファイルと、プロファイルの並び順に違いがあります。

   .NET 5 (VS2019)       .NET 6 (VS2022 Preview)    
f:id:hiro128:20210928022256p:plain f:id:hiro128:20210928022309p:plain

 
デフォルトの起動プロファイルは、単純に、[AppName].csproj.user の ActiveDebugProfile の値で決まりますので、.NET 5 でも値を修正すれば デフォルトの起動プロファイルが Kestrel になります。

Kestrel の方が軽いですし、クロスプラットフォームなので、既存の .NET 5 のプロジェクトでも デフォルトの起動プロファイルを Kestrel に変更したい場合もあると思います。
 

.NET 5 の例

WebApp2019.csproj.user 初期値(IIS Express デフォルト)
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
  </PropertyGroup>
  <PropertyGroup>
    <ActiveDebugProfile>IIS Express</ActiveDebugProfile>
  </PropertyGroup>
</Project>

 
f:id:hiro128:20210929004743p:plain
 
 

WebApp2019.csproj.user 変更後(Kestrel デフォルト)
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
  </PropertyGroup>
  <PropertyGroup>
    <ActiveDebugProfile>WebApp2019</ActiveDebugProfile>
  </PropertyGroup>
</Project>

 
起動プロファイルが Kestrel に変更されました。
f:id:hiro128:20210929005311p:plain
 
 
 
起動プロファイルの並び順については、[AppName]\Properties\launchSettings.json 内の記載順で決まりますので、こちらも順番を入れ替えれば、 Kestrel, IIS Express, WSL の並び順を自由に入れ替えできます。
 
 

launchSettings.json 初期値(IIS Express が最初に記載されている)
{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:27769",
      "sslPort": 44341
    }
  },
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "swagger",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "WebApp2019": {
      "commandName": "Project",
      "launchBrowser": true,
      "launchUrl": "swagger",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "dotnetRunMessages": "true",
      "applicationUrl": "https://localhost:5001;http://localhost:5000"
    },
    "WSL": {
      "commandName": "WSL2",
      "launchBrowser": true,
      "launchUrl": "https://localhost:5001/swagger",
      "environmentVariables": {
        "ASPNETCORE_URLS": "https://localhost:5001;http://localhost:5000",
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "distributionName": ""
    }
  }
}

 
JSON の記載順通り IIS Express , WebApp2019(Kestrel) , WSL の順番になります。
f:id:hiro128:20210929005331p:plain
 
 

launchSettings.json 順番入れ替え済み(Kestrel が最初に記載されている)
{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:27769",
      "sslPort": 44341
    }
  },
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "profiles": {
    "WebApp2019": {
      "commandName": "Project",
      "launchBrowser": true,
      "launchUrl": "swagger",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "dotnetRunMessages": "true",
      "applicationUrl": "https://localhost:5001;http://localhost:5000"
    },
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "swagger",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "WSL": {
      "commandName": "WSL2",
      "launchBrowser": true,
      "launchUrl": "https://localhost:5001/swagger",
      "environmentVariables": {
        "ASPNETCORE_URLS": "https://localhost:5001;http://localhost:5000",
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "distributionName": ""
    }
  }
}

 
こちらも、入れ替えた JSON の記載順通り WebApp2019(Kestrel) , IIS Express , WSL の順番になります。
f:id:hiro128:20210929005347p:plain
 
 
小技ですが、必要になったときに結構忘れたりしますので、備忘録として残しておきました。