de:code 2019 [CM12] .NET Core マルチ プラットフォームの本質

Microsoft de:code 2019に参加した内容を紹介します。

もし間違いなどあれば、ご指摘いただけますと助かります。

...正直ついていけているか怪しかったので、誤解して聞いている可能性は高いので遠慮なく...!
ビデオが公開されたらそちらを確認された方がよろしいかと思います。

とりあえず、**[サンプルコードと解説](https://t.co/cRGXzz8Cws)**を見てみるのがおすすめです！

# [CM12] .NET Core マルチ プラットフォームの本質 / 2019年5月30日

# TL;DR（要約）

- Core CLRもGitHubにリポジトリを出しているが、この中のmdファイルが、一番大事なドキュメントとなる。
- クロスプラットフォームのために、Bait And Switchが実装されている。
- .NET Frameworkが廃止される。クライアントサイドは、.NET Coreでも.NET Frameworkでも関係ない。サーバーで機会があれば、.NET Coreとすればよいのではないか。新規案件があれば、.NET Coreで実装するという考え方でよい。

# リソース

- [セッション詳細](https://www.microsoft.com/ja-jp/events/decode/2019session/detail.aspx?sid=CM12&kw=CM12)
- [サンプルコードと解説](https://t.co/cRGXzz8Cws)

# 内容について

始めに断っておくが、**こんなセッションに来られる方は物好きなかた！**

# CLIの基礎知識

![](https://w5dppq.bl.files.1drv.com/y4mMlajVEm2BeK8PWhYYJ4G62f_kXPStuP03tJiW4KtFWYXksk_cIE30QP877HgnJyYelJkMOGTUBoAW2X9dj573BWowNTATKQoo4l176bgjWUAYvf-yvHR4X1UQlirYU48-6KluKJWP1mDx5Ui4XbvM-eD1XCsIqnRKNEEXNJqvMfsjIAeo2LUK9tWhZtw5HY_dez7JYxS0GNwg3wx2O-yZA?width=1280&height=593&cropmode=none)

## ライブラリを作るための規格

JISで決まっており、オンラインから参照することができる。

### 資料の1-6に乗っている内容で重要なのは

- 共通型システム（CTS）
- 共通言語仕様（CLS、相互運用）

.NETで、CLSに相当するものが`.NET Standard`

これは、標準規格なので、実装は何もない

## メタデータ

メタデータとは何なのか？
PEに対応する リトルエンディアン

色々な言語ができた中で、CLSが一番大事である。


# 【デモ】

```
windbg wpfapp.exe
```

Core CLRに設定している。サウンドストライクを読み込むのに、`loadby`というコマンドを呼んだのは、core clrを読み込んだ後に呼ぶ必要があるから

デバッガー拡張が読み取れたので、ブレークポイントを設定した。

## DumpDomain

![](https://w5dspq.bl.files.1drv.com/y4mvWp8PYcLdWTLGfDmasRVMYT49TYUokKmm_DfMiUPTZ3G231_ywcybckjosFDH-w5qtrqF19zIeVWXKB0nDGYRDV0wMO4Cy3mVs_sd7HrSVnBFXOCnS-t4Tf2zQZt1wf4wPcYtzVO_Jgi8aKZm6lZYdBTzNUyt6iKX6wmfGd7RFvK9AtQUUDJaY33AnQz4WVI3FpQWigJqUHZtI1h_d7fPw?width=1280&height=787&cropmode=none)

.NET Frameworkの場合には、デフォルトでアプリケーションドメインが3つ

Core CLRの場合には、2.0になってから、UpDomainクラスというのが再定義された。
もともとCLIが呼ばれているのことからわかるように、Applicaton Domainごと。

プログラマーにApplication Domainクラスを開放しているかどうかが.1.0と2.0の違いとなる。

# VESの仕組みを考えてみる

![](https://w5drpq.bl.files.1drv.com/y4mAJy68qCCwoCB1irQuIRdssPAecvhXp99iePgzcmxlJyF-y3LboH0U0rLRRwV6rHxIvgywc-q5V_K4LcZKI5nX5DRVJC5-YLx1C1p60KwXDJ-9_fb4qg4FvL6qRzqki5Hq92Gi9G2KDTGoiUHAL-qSy1dHPq5Ac6Lony8hzweN1FRUpQDhHawc9vF1sa5mD3UISo5a6mm_S9JH_FTj1f-0Q?width=1280&height=640&cropmode=none)

クラス単位にメンバーをディスパッチしているものが呼ばれる。
初回にはJITが呼ばれていない。JITが呼ばれてポインタが作られる。
2回目以降はネイティブコードがあるのでそれを使って実行される。

`DumpLE`というコマンドを見れば、どちらかがわかる

![](https://w5dtpq.bl.files.1drv.com/y4mpRJ5aJQl8j0x14z5k6qtgbkgwGE6yVBqLf1MV4bUUI6JJXe5Zqa8zitAiZ-ebEkL2-A-TDaIVPaLaLeXLu9ekFqp7WyACqLABiE8p_0LScUxKqrAHNC4RpDaKKnXaCbgaN-5XlM2sYUE6fxKkuc-IAHaGXnrd1vhrRwCM2YcqMdxQ95DB0YSJi5MUqQYNyOgk5xpKjAA7lng3kg6Bq7YPA?width=1280&height=706&cropmode=none)

## 標準規格とは？

標準規格が定義しているのは、INとOUTが規格通りであればよい、というもの。


## .NET CoreとTarget Framework

![](https://w5dmpq.bl.files.1drv.com/y4mtK_ID2hnIf20c42_rYgMP9dz9gQSoJ0xg5_-nQbIWf2RlJwMFZAB-IZ6RHDPYnbwcrXFpoV6QFT-SXGsPNSDvjoG0W0PeJVICF2oz8MybWFrSEHuhA5jYbDtODmzMdB6AVMa5MWLkpz-c-z5GImrf2lN9V8irSROk4EjyITqa6nAUIJBwGTHTphYRzOiBjVMVk5C5NOBiUhMK9QD_wx7Yw?width=1280&height=713&cropmode=none)

## 共通型システム

既定の型はすべてSystem.Object。

## BCLの互換性

![](https://xjdnpq.bl.files.1drv.com/y4mVB4RMkFl3NvNZcsELy9m3th3hiwsXM1ATLkiIiLLnkdTaep0iBlks7VqrLKPkNnCAYWHo41m6Lh360XgYq5n1uMfgPcESfm3b4fMc9VnC8r_Fh0ZpLmXbZTU8C3N0H4zDOj5PNjzjSI1Y5i2dxOEE6QCsX_hUkbMNH6OrvCM29vMMHK1_qr2Ylv2mVksJVikv3kzeT0gxh0q6GYvhDBM1Q?width=1280&height=700&cropmode=none)

NET Core 2.0になった時に、Core CLRに移った。

## BCL（Base Class Library）

# GitHubに公開されている重要なドキュメント

Core CLRもGitHubにリポジトリを出しているが、この中のmdファイルが、一番大事なドキュメントとなる。

### mdファイルに記載されている内容が大事！

1.0から2.0に移る際にチェックインされたドキュメント。Common Language Runtimeを作成するときに作られたドキュメント。

なぜMscorlibが特別なのかということが書いている。

# GCの仕組みを知ろう

GCというのは、メモリ上のものを回収している。実行エンジンというものは型が何かを知らないといけない。System.ObjectやGCが何をするかを知らないといけない。

Managed 実行と UnManaged実行のコストの問題上、QコールとFコールが用意されている
Qコールは直接呼ぶものであり、Fコールはメソッドテーブル

## ILSpyを実行して確認する

Qコールは、初期化する際にマウントされた実態であり呼び出されたもののオーバーヘッドを限りなく小さくしている。なので、MSCorlibはとくべつなObjectである。

# メタパッケージ

![](https://w5dkpq.bl.files.1drv.com/y4mKJQpR4XNn_enWaa7NU96bZ5pRUlkSMpYdj5UVtfegsOpkIydeNaCxPgIhUkuZohtzNmeHStlHgJVl37xEFGSOlkaMMyaWQGFl2u9Gs5pgEseGLiXGUIC44MicwhnM_5zjrf3qmIvCeNNtEH-4FhkhWkpHx-1Y7mtEN_5qC8oTTVcCTu5T50TH6GRMUYutZKkXwhslth1RBBySowr2fiK7Q?width=1280&height=652&cropmode=none)

#【デモ】型を参照するとは？

型を参照するとは、どういうことを示しているのか？そこで、メタデータが実際にどのように見えるのか、ということを見せましょう

- string heapを見てから必要なものを探す
- メンバーはメンバーリファレンステーブル。
- シグネチャは、戻り値などを符号化したバイナリの値。引数の型が変われば符号も変わるなので、オーバーロード
- 今は、C#は戻り値のオーバーロードは許可されていないので、うまくいく
- 型を参照するのは、AssemblyIdentiry以外は、名前と値で区別している

**メタデータを見るのは慣れないと結構見るのはつらい**

# Bait And Switch

![](https://w5dlpq.bl.files.1drv.com/y4mEboGJL2VZTt9PKqs25gIYTTgqamGBS0ePu8bJjaNseUOWNmEhyrbHiTXpaSNyyOtphUgCCD-n-K6IOGzZ9yqkT8qX_ZqT1esKh0zV0t_Bq6jR8YvUG2QeJrhIvAZCsBcC9Q8HcFJfAE5Uam7KqOyrjaZCQ4CNhPPBMBNg7yQRNJZfpOMY80omG_Oom-gR1u4N4Qf--iEHLeyqRumT7Y9JQ?width=1280&height=646&cropmode=none)

Nugetが基本となっている

単純に言うと、コンパイルするときに見に行くアセンブルと発行するときのデプロイ用のアセンブリが違う。
実装するときのアセンブルとコンパイルするときのアセンブリが違ってもよい、という考え方となる。

## なぜこういう仕組みを実装しているのか？

クロスプラットフォームのため。

コンパイルするものと、実際に動くものを差し替えてみる（メタデータの特徴を活用したテクニック）。それでも動作する。

要は、名前とシグネチャが一致していたらなんら問題ない（実行時の仕組み上も、実行エンジンはエラーを出力しない）という仕組みは、こういうところに支えられている

# メタデータを支える技術

![](https://xjdtpq.bl.files.1drv.com/y4mPEYD-NFjzV-EcgxyxbVclYwzUhPSx6hLfO2sckZ8rmLIgYtpp4xgd8xvJ7ag1CF6fYQqVWWAPbO4mAEWgvwq-SH_tADl1L_TsQhG16f-opWwe3bYBCYvfZUzsV3ohCeTaZP-defcQ8V0tT5UYRhsuev6IFPm9Wq08-HuchlAjiHvyDsvh3dZt52VmyDv1q6y1dyustmBPq7kqWQjCeAZLw?width=1134&height=556&cropmode=none)

自分でNugetを作るときに、自分がどのランタイムをサポートするかということを考えないといけない。

今は、.NET Standardというものがある。共通のAPIセットがあるわけなので、これに沿っている限りは、考えなくてもよい。

**相対的に、.NET Standard Library 2.0ができたことで、あまり考えなくてもよくなった。**

# アプリの展開方法

![](https://xjdkpq.bl.files.1drv.com/y4mPt2e2bLDtU_UZxy4HFdc8ZjyvwUQo0pDdf5jmgJlOeohHAqzS82CQ7NDk0wvmemYKOTQJkGt3EjdtPic2o31Q_cYyWEo--jUNS53EAsI-DqojJapy578gZ4w7Wf8Vrn7chFm5muArovDUrP_aNozDSCZEvkVP2ZRCzfqMzT4SQM4vGi_7qkb5kYvoVNNILDGC-ap49Ff9grdcQvKp7wXSQ?width=1280&height=693&cropmode=none)

ASP.NET はFDDである。.NET Coreで作成した場合も、FDDというところは変わらない。

# .NET vNext

![](https://xjdrpq.bl.files.1drv.com/y4my0nuFbpFk7dZJqmVHxcbGzlSg-F4DcKyYWn8iI1p1GdvXaoWU9JlhbZuiZ-MIT75RhQf4mZ84Eujbj7XeGfYbUcbxigvBb8bQCqcN-b6oO2mElOdh4g1yhLyJSicHnBe_nnJvZh0aS6NvenxLcMXHjmuh5V7x8QD94Hq3Ve1LAu-0DrlcfoziUBL2jBdGGCKWlyJ7aBX4fn1jLNf_wJ6TQ?width=1280&height=675&cropmode=none)

## .NET のサポートライフサイクルが短い

セキュリティ事故が見つかった時にどうするか。**毎年毎年リコンパイルが必要だ**、という考えのほうがよい。展開の問題はあるが、サポートライルサイクルは、それぐらい短くなっている。

## .NET 5では、1フレームワークに集約

###  wCF

- Web APIへ移行

### WF

- OSSで実装する。

### Web Forms

- ASP.NET MVCへ移行。これはViewとしてBlazorを利用するということ。仕組みの基本にあるのは、ASP.NET MVC

### Remoting

- RESTやgRPCへ移行

### AppDomain マルチホスティング

# 新井さんの考え方

.NET FrameworkでのC#はどうなるのか。バージョンが上がっても、サポートされる。言語、ライブラリではない、コンパイラが解決する。Roslynが解決する

# まとめ

![](https://xjdmpq.bl.files.1drv.com/y4m0rfT1_1b6h-PPx806uTG-9hVL4BmI1jED9fjmR87cDTzsjFB79LUh-Bymk-LHTfCG94EhDKeOaSSTqbsAuNyoA8umQOolnBRxNYm7Cit0GaEuAQV4iNNi51RKUjjJpV50ZyVbbcc-5JR82DMwytqlVJ-8nPK9bQjiiWWzds1b4rj_zM6YmWbHwjNs7dzkKEofrg0Q0Gt0JucKrlZe5S3HA?width=1280&height=662&cropmode=none)

- 実装に互換性はない。
- Microsoftとしては、.NET 5に一本化する
- .NET Frameworkは4.8で開発終了、サポートはずっとされ続けるので、OSの1コンポーネントに過ぎないので、サーバーサイドとしても問題がない
- クライアントサイドは、.NET Coreでも.NET Frameworkでも関係ない
- サーバーで機会があれば、.NET Coreとすればよいのではないか
- 新規案件があれば、.NET Coreで実装する

## Appendix

- JISについては、日本からでないと見れないようになっている

## 最後に

.NET Coreでちゃんと開発しようと思ったら、どういう風に実行されているかをわかったほうが望ましい。すべてGitHubに公開されている。移植はものすごくまじめに行われている。