One .NET時代のC# Web開発における技術選択を考える

# はじめに

レガシーC# (.NET Framework) + ASP.NET MVCでWeb開発をしているIosif Takakuraと申します。この記事については私個人の見解であり、所属する組織の見解では無いことを申し上げておきます。

最近.NET 5.0がリリースされ、多くのプラットフォームでの実装が.NET 5.0から続くOne .NETに集約されつつあります。しかしながら、エンタープライズな.NETの世界では.NET Frameworkが生き残っていることも多いと聞きます。そのような世界では様々な事情から新しい.NETへの移行が考えられていないことも多いです。

その一方で、最近ではLinux上で.NETを動かす例があったり、ゲーム開発の世界で Unity[^1]が幅広く用いられるようになり、.NETの世界への参入障壁が徐々に下がってきています。その中で、CySharpの河合宜文さんによる「C#大統一理論」という、サーバサイドとクライアントサイドを全てC#で統一する開発手法が提案されていたりとC#の世界も変化しつつあります。

[^1]: ゲームエンジンの方。UbuntuのUIでもMicrosoft製のDIコンテナでもない。

また、BlazorなどのWebAssembly技術の登場でWeb開発の世界にも変化が予想される中、WebではJavaScriptやTypeScriptでサーバサイドも開発しようとする流れ、とりわけTypeScriptでサーバサイドとクライアントサイドの世界をひとまとめにしようというフレームワークもいろいろ登場し、「TypeScript大統一理論」もあり得る時代になってきました。

その中で今回はどうやって技術選択をすべきか考えていきたいと思います。

# 今後のC#を見据えた展望

先日、[C# Tokyo オンライン フリートーク・ディスカッション 2020/12](https://csharp-tokyo.connpass.com/event/196893/)というオンライン座談会に参加してきたのですが、参加者はエンタープライズ系開発者が多く、その中で.NET Frameworkを使っているエンタープライズ開発者ならではの悩みも多く上がってきていました。その議論の結果を踏まえつつ、今後のC#の展望について私が思っていることをお話しします。

## .NET Frameworkから.NETへの移行について考える

開発者の側からしてみれば、新しい.NETやC#に惹かれてしまうのもわからなくも無いですが、システム管理者サイドや経営サイドからしてみると.NET Frameworkを使い続けた方が楽という状況も見えてきました。ざっと考えると、以下のような理由が挙げられます。

1. 新しい技術の学習コストが大きく、情報を得た上で検証する機会が少ない
2. 「情シス」が忙しすぎて、検証している余裕がない
3. 新しい環境へ移行するリスクを冒してまで新しい技術を使うメリットが見えてこない

この場合は、新しい技術に移行する価値をユーザーサイドや経営サイドに説明できないと新しい技術を使ってもらえるかは難しいと思います。とりわけ、ITを収益システムと考えていない会社の場合は厳しいといえるかもしれません。そういう.NET Frameworkでよいやという企業がある限り、Microsoftもサポートを切れないのでは無いかと思っています。

### 2020-12-15 追記

しかしながら、パフォーマンスを考えると.NETの方に分が上がります。[TechEmpowerのベンチマークのComposite scoresの結果](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=composite)を見てみると一目瞭然です。新しい.NET Coreの方は6位に位置しているのに対し、.NET FrameworkのASP.NETは103位、ブービーです。ここまで来ていると性能差ははっきり見えてきます。それに加え、.NET Frameworkは今後新機能の追加は無いとのことなので、おそらく現状維持から衰退していく一方だと思われます。そうなると、新規開発では.NETで開発した方がよいように思われるのです。

## C#とTypeScriptと大統一理論と

最近、フロントエンドをC#で書けるBlazorというUIフレームワークが出てきました。Blazorを使う場合でもJavaScriptを書かなくてよいというわけではありませんが、そうなってくるとフロントエンドのNode.jsエコシステムとの連携が問題になってくると思います。

なお、現状ではフロントエンドはJavaScript/TypeScriptの天下なわけですが、フロントエンドとバックエンドを一つの言語で、一つの型システムで書きたいという要望はあるわけです。その動きとしてTypeScript用の[Prisma](https://www.prisma.io/)というORMを使用し、それらを組み込んだ[Frourio](https://frourio.io/)や[Blitz.js](https://blitzjs.com/)といったフルスタックのTypeScriptフレームワークが登場しはじめています。そんなTypeScript界隈からの挑戦状として[Re: Rails を主戦場としている自分が今後学ぶべき技術について](https://zenn.dev/mizchi/articles/d33a4174cca886)という記事が話題に上がりましたが、Blazorの普及は以下の2つの課題が解決されないと厳しいのではないかと思っています。

- 「WASM GCが仕様化されるまで、出力サイズが厳しい」[^2]問題
- C#ユーザーにしか使ってもらえないかもしれない問題

もちろんJavaScriptエコシステムの側にもNode.jsとDenoの問題があり、エコシステムの混乱は起こりうるでしょうが。

[^2]: [mizchiさんの受け売り](https://zenn.dev/mizchi/articles/c638f1b3b0cd239d3eea)。

## デスクトップかWebか

次に問題になるのがシステムをデスクトップアプリとして作るのか、Webアプリとして作るのかという点です。私は普段からC#をWeb開発に使っていますが、先日のフリートークではWPFなどのデスクトップアプリケーションを開発している人も多かったです。

その中で気になっていたのが、C#でWeb開発をすることの意味です。正直なところUI面ではWebはデスクトップアプリケーションに及ばないわけです。WebでリッチなUIを求めるならNode.jsエコシステムの助けを借りる必要が出てきますが、Webで開発を行う以上、バックエンドのC#の世界とフロントエンドのNode.jsの世界は分断された状態になります。デスクトップアプリケーションなら全てC#の世界で完結できるわけです。ゲームなどの最新技術が求められる分野ではC#大統一理論の恩恵を受けることもできます。おそらく、C#でWebを作る理由は配布や管理の手間の軽減にあると思われますが、現時点では配布や管理の手間はIntuneなどで格段に楽になったといえるでしょう。Xamarinで書く場合もAppleやGoogleのストア経由で配布できるので、昔みたいな配布の手間は少なくなったといえます。

そうなると、あえてWebで開発する意味はあるのでしょうか？そこには、開発者のレベルの問題があると思います。Webで開発するならスキルセットはWebの延長線上ですが、デスクトップアプリケーションやXamarinの場合はWebとは異なるスキルセットが必要だと思います。そういったネイティブアプリの育成に人が追いついていない現状もフリートークから感じられました。

それを考えると、デスクトップアプリケーションを作れるならデスクトップアプリケーションで作った方がよいものの、現実的には人が足りないので難しいと思います。

## 業務アプリケーション開発者から見たUnityの世界

また、私は、現時点でUnityの発展がC#を牽引するだろうと思っています。ゲームは業務システムとは正反対な、以下のような特徴があります。

- それ自体が収益源となる
- ある程度パフォーマンスやUIがよくなければ売れない
- 最新技術の恩恵を受けやすい

そうなっていくと、C#のパイが広がるためにはゲーム開発がもっと盛んになっていくことだと思っています。.NETがLinuxで動くようになったことで、参入障壁はかなり下がったと思います。後はUnreal Engineを巡るAppleとEpic Gamesの問題でどれだけの人がUnityを使うかを注目する必要がありそうです。

# まとめ

ということで、いいたいことをざっとまとめると以下のような感じになります。

- Blazorは今後に期待するしかない
- TypeScript大統一理論はC#のよきライバルとなると思われる
- デスクトップアプリケーションを作れるならデスクトップアプリケーションを作るべき
- C#エコシステムの発展はUnityの発展に期待

さて、現時点で堅実なWeb開発の組み合わせとしては、フロントエンドはNode.jsエコシステムに頼りつつ、バックエンドをASP.NET Core Web APIで書くことだと思います。それにしても、私がこんな環境を使えるようになるのはいつになるのでしょうか。