2019/07/02

C#のちょっといい話01 C#の現状

おそらく仕事では1、2を争うほど使っているC#だが、これまで取り上げてこなかった。まぁ別に書くことないしな、くらいに思ってたが、友人なんかに聞いたら結構需要があるとのこと。
自分も便利だから使っているわけで、XamarinとかUnityとかでC#人口は上がっているし、よし、いっちょやってみっか!的な決心をした。

ただ、C#って.NETと違うの?とか.NETのバージョンとC#のバージョンとかあるけどどっちが重要?とか聞かれたので、ちょっと枠組みがわかりにくそう・・・ということではじめはC#周辺の枠組みの整理と現状なんかを説明したい。



C#とは?


C#とはプログラム言語で、もともとJavaあたりに影響を受けて策定された。立ち位置もJavaに似ていて、色々な面でC++とJavaScriptの中間のような、まぁちょうどいい存在。自由さも中間、パフォーマンスも中間、だが、それがちょうどいい。
おおよその特徴をあげると
  1. クラスベースで、インターフェースサポート
  2. プロパティサポート
  3. 関数、演算子のオーバーロードサポート
  4. インスタンスの値渡し、参照渡しあり
  5. 関数型(デリゲート)、ラムダ式サポート
  6. ガーベージコレクタサポート
  7. 非同期処理の枠組みのサポート
といったところだが、挙げればきりがない。(あと、サポート状況はバージョンにもよる)
Javaというより、JavaとC++からいいとこ取りして、あまりこだわりなく便利そうなら色々取り込んでいった、といった感じか。
C#にもバージョンがあり、現在ではC# ver.7系までリリースされている。

ここで「C#でアプリ書いてたら.NETのバージョンのこと聞かれたんだけどC#のバージョンと違うの?」という質問があった。結論からいうと違う。では.NETとは何か?


.NET


.NETこと.NET Frameworkとはマイクロソフトが提供しているアプリケーションの開発・実行環境で、C#のみならず、VBで書かれたアプリケーションも.NETアプリケーションと言う。.NET Frameworkは使用できるライブラリ(SDK)と実行環境が合わさったもの、といった感じだ。
Monoなど別の開発・実行環境もあるので、C#は別に.NETに限られた物でもない。とはいえ、C#でかける環境ではある程度.NETと互換性を持たせることがほとんどなので、密接な関わりではある。ある程度使えるライブラリは同じで、ソースコードの再利用性が高い、というのも特徴ではあるだろう。つまり「.NETのバージョンが異なる」とは「使用できる機能が異なる」という意味となる。
一方で、「C#のバージョンが異なる」とは、例えばswitch文の条件式で扱うことができる型が異なる、などの違いなので、もっと基本の言語仕様の違いとなる。

.NETでは、使用できる標準ライブラリの機能が豊富である、というのも大きな特徴となっている。例えばJSON形式のデータを扱いたい、という場合、.NET ver.3.5以降ならDataContractJsonSerializerというクラスがあるので、外部ライブラリや自作ライブラリが必要ない。
NuGetというライブラリのエコシステムも使用感がよく強力で、プログラムを作る工数が昔に比べて大幅に減っているのは確かだろう。


この.NETはもともとWindows環境でしか動作しなかったので、長い間C#はマイナー言語だった。少し前からMonoという.NET互換のマルチプラットフォームの開発・実行環境が出て、C#はマルチ環境でアプリを作るのに適した言語として注目された。また、C#は言語仕様が洗練されていたこともあって人気がでて、様々な分野での採用がなされてきた。


余談だが、最近マイクロソフト自身がマルチプラットフォームな.NET開発、実行環境を出してきて、それ自体は好ましいことだと思うが、また別のバージョンが出てきて皆を悩ませている・・・(.NET Coreといい、これも独自のバージョン付けがある)


C#のバイナリ形式


少しマニアックな話だが、C#で作るライブラリや実行ファイルがどのような形式になっているか、も重要な特徴なので、説明しておく。

C#がコンパイルされると、中間言語(CIL)のバイナリファイルに変換される。実行時には、この中間言語を機械語に翻訳しながら実行するわけだ。
この中間言語はプラットフォーム依存がないものなので、例えばマルチプラットフォームのMonoでは同じ実行ファイルをWindowsでもMacでも使用できる。これはライブラリでも同じで、1つのライブラリファイルをどの環境でも使用できる。先にNuGetというエコシステムの話をしたが、例えばC++ではWindows用のバイナリファイル、macOS用のバイナリファイルなど、各プラットフォームごとにライブラリを用意するか、ソースコードを提供して開発者が勝手にビルドしてね、という提供方法しかなかった。これが超めんどくさかった。
NuGetでは1バイナリをビルド、アップロードすると、それをどの環境でも使用できる。ライブラリの使用者は1コマンドで対象のライブラリと依存ライブラリをダウンロード、組み込みができるので、提供者、使用者ともにストレスが少ない。

ただ、この仕様のせいで困ったこともあった。iOSなどの環境では、アプリは中間言語を翻訳実行するような仕組みは許可されておらず、マーケットに乗せることができない。そのため、Monoなどマルチプラットフォーム提供を目的としているプロジェクトでは、この中間言語をあらかじめ機械語に翻訳したバイナリを作る技術で対応している。

この技術は思わぬ恩恵がある。翻訳実行は便利だが、実行時のパフォーマンスがネイティブよりかなり劣る、という問題があった。翻訳している分当然なのだが、かつては「C#は重いよね」みたいな印象が開発者をC#から遠ざけていた。ただ、あらかじめ機械語にしておくとパフォーマンスはネイティブに近くなるため、携帯アプリやゲームなど、パフォーマンスが求められる分野にも採用されるようになってきた。

最近では有名なゲームエンジンでもロジック記述にC#が採用されることが多くなっており、以前に比べて使用範囲が格段に広がってきている。


採用やこれからの動向


これまでは、スマホアプリはAndroidをJavaで、iOSをswiftで書き、ゲームはC++、WebアプリはPHPで書いていたわけだが、冷静に考えると狂気に近い。(自分は今でもこれらで書くことが全然ある)
例えばデスクトップアプリを作る場合はMonoアプリケーションで作成し、スマホアプリなどはXamarin環境で組むことができる。ゲームはUnityで作成し、WebアプリはASP.NETで実行する。これらは全てC#でかける。

一つの言語で書くと知識が深まるので、楽だし当然品質が上がる。その言語が使いやすいものであればなおさらだ。その像にかなり近いのがC#であり、C#使いの多くが「全部C#で書きたいよ病」を発症するのは当然の流れなのだ。

また、マイクロソフトが提唱した.NET Coreはマルチプラットフォームの.NETアプリ開発・実行環境で、従来のデスクトップアプリなどに加えて、Webアプリケーションも視野に加えている。上で「WebアプリはASP.NETで」と書いたが、これからは.NET Coreで、と説明することになりそうだ。

さらにオープンソース化がすすんでいて、コアライブラリ、コンパイラ、開発・実行環境などが次々とオープンになっている。そのため、品質向上や仕様策定ステップの民主化が進み、C#の採用がさらに加速しそうな状況となっている。


使用感


これは個人的な感想なのだが、C#でアプリを書くのはかなり楽だと感じる。何となく書いても動いちゃったりする、というのが正直な感想だ。

例えば非同期処理を含むアプリケーションを書く際に、「最終的に実行テストしながらロックとか検証しないとなー」と思いながら、はじめはロックなしで書いたりすると思うが、この状態で動いたりする。これは偶然と奇跡がなせるワザ、ではなくて、言語仕様的に非同期処理を同期処理のようにかける枠組みがあるため、問題なく動いたりするのだ。

ライブラリを1コマンドで導入できるのもいい。「割と適当に書いても動く」という特徴も、品質の向上にうまく繋がっている感がある。



褒め通しだが、Monoが重い時代には「使う意味がわからん」など結構過激なことを言ってました。すみませんでした、Monoさん、MSさん。今はないと生きていけません。
次回からはC#の基本的な書き方を説明していく、わけではなくて、このシリーズではちょっと変わっているけど便利なC#の機能などを紹介したい。

0 件のコメント:

コメントを投稿