C#言語で出来ること


C#言語で出来ること

 最近、長年Webで連れ添ったPHPを捨ててC#言語一本で何でもやろうという気になってきた今日この頃。今後、C#言語についての話題を書いていこうと思い、この言語の紹介をしてみることにした。

 この言語?...というよりは、この環境(dotnet)は、ほぼオールマイティーなプラットフォームで、出来ないことがほとんどないというような環境になりつつあります。元々、Windowsでしか動かせない(十分なのですが)狭いプラットフォームではあったのですが、今やLinux,Mac,Android,iOS,コンシューマーゲーム機でも動かすことができ、様々なライブラリが用意されています。環境の差はあるので、AIはあまり得意でない、ライブラリが事足りないというのもあるけれど、オープンソース化もされているのでそれも時間が解決してくれるような気がします。

 以前ならば、この分野はJavaが唯一の利点であったのだけれど、有償化とオープン部分での不安要素を突き上げられてどったんばったん中ですしね。まぁ、猫はJava言語と環境は嫌いなのでどうでもいいです。

 さて、2000年の.NET1.0登場以来、ずっと発展を続けているC#言語と.NETで出来ることは?...というのを、ちょっと纏めてみました。


ネイティブとインタプリタ【実行形態】

 ネイティブとは、この業界では「機械語」のことを示し、ネイティブコンパイルというと、ソースコードを機械語に翻訳し、直接CPUにて実行できるコードに変換されることを示すことが多いと思います。

今まで提供されていたC#言語と.NETでは、コンパイルすると中間言語(MSIL)に変換され、インタプリタ(逐次実行)としてプログラムを実行する形が唯一でした 実行時に、わざわざ中間言語をその環境のネイティブに変換してから実行を開始するというJITコンパイル方式(実行時コンパイル)を採用していました。

 中間言語方式では、必ず実行環境上でインタプリタを必要とします、実行時にネイティブに変換してコードを実行させるか(JITコンパイル)、中間言語を解釈できるインタプリタに解釈させて実行させる方式のいずれかになります。

 また、PHPやJavascriptとは違って、中間言語は、各言語の構文解析や意味解析などを行い、比較的ネイティブの環境に近く解析しやすい構造になっているため、実行はPHPやJavascript等の言語に比べて、解釈する速度が早くなりますが、あらかじめネイティブとして出力されている実行形態と比べ、exe実行時に、JITコンパイルを用いて中間言語をネイティブに変換、それから実行という流れになるため、その点、起動の時間差によりネイティブとの実行の差はでてしまいますし、JITコンパイルによるコンパイル時間が長いと本来動かしたいコードが起動するまでにかなりの時間がかかる点は残されていること、そして一般的な事前コンパイルして出力されるネイティブコードと違い、コードの最適化を行う時間の余裕がないために、実行速度がC言語等でコンパイルしたコードよりも遅くなるという点はあります。

 でも、現在のC#言語は違います。ネイティブのコードを吐き出せます。正確には、今までもJITコンパイルにより、ネイティブ言語を出力していたのですが、AOT(aHead of Time)コンパイルと呼ばれる、いわゆるC言語などが行っている事前コンパイルを.NETおよびC#言語自体ができるようになったのです。

 その、事前コンパイルが行われてる仕組みは、現在、Windowsで使われてるUWPが対象になります。また、iOS向けのC#(Xamarin)もネイティブでの実行になります。iOSは、動的言語を禁止しているため、事前にネイティブ(ARMネイティブ)にコンパイルしているのです。

 インタプリタの件について、よく調べると勘違いもあったので、記事を修正したため、スクリプト言語に関する情報が消え去りましたが、C#言語はインタプリタでも動作します。Power ShellやMicrosoft.CodeAnalysis.CSharp.Scriptingを使うことで実現が可能ですし、Visual Studioにも検証としてコードを書いて実行させる機能があります。

 また、MonoについてはJITコンパイル環境が用意されているものは実行時コンパイルで実行しますが、JITコンパイルが用意されていない環境下では、インタプリタとして実行するようです。

 このように、ネイティブ(JITコンパイル、AOTコンパイル)でもインタプリタでも動かせるという特殊な言語になっています。


ネイティブ・中間言語・インタプリタ(スクリプト)【動作形態】

 上で分けたネイティブ(AOTコンパイル、JITコンパイル含むネイティブ実行)とインタプリタ(逐次実行)は「実行形態」としてです。実行形態は、ネイティブで実行するかインタプリタとして実行するかの2種類しかありません。

プログラムを動作させる形態としては、3種類になります。

そして、C#言語は、すべてに対応しています。

 ネイティブ(事前コンパイル)による各機械語(x86,x64,ARM)は実行形態であげたとおり、WindowsとiOSで対応しています。C#言語には、ポインタを扱える機能があるので、Javaと比較してもネイティブとの相性はいいかもしれません。なお、ネイティブに事前にコンパイルしてあると、ある程度型情報が吹っ飛んだりする関係上(機械語には、各プログラム言語にあるオブジェクト指向のような概念などは存在しないため)、一部使える機能に制限が出たりします。現在、x86/x64/ARMに対応していることになります。

 中間言語(MSIL)は、.NETの元からある機能です。基本的にネイティブ変換されない場合は、中間言語方式にコンパイルされて実行時にJITコンパイルを通して実行、AOTコンパイル(Ngen)、インタプリタで実行する形になります。Windowsでの実行形式拡張子は exe、.NET Core で実行する場合は dll が主流です。

 インタプリタ(スクリプト)とは、C#言語で書かれたコードをインタプリタに渡して解釈させ実行する形態ですが、今までのC#言語はソースコードをコンパイルして中間言語に変換し、各種実行する形態しかありませんでした...が、今のC#言語はインタプリタを内蔵させて実行させることが出来ます。

Microsoft.CodeAnalysis.CSharp.Scripting

このライブラリを入れることで、環境にインタプリタを導入できます。また、VS2015より環境自体にインタプリタのテストを出来る機能が入っています。


できること


GUIを持ったアプリケーションの開発


  • Windows

  • Mac

  • Linux

  • Android

  • iOS

Linuxは、Monoを通すことで、WindowsForm も通せますし、GTK#とやらもありますs、VisualStudio for Macを使うことでMac用のネイティブGUI環境も作ることが可能です。Android/iOSはネイティブのSDKで実装することも出来ますし、マルチプラットフォーム用のXamarin Formを通せば複数の端末向けに同時開発できます。


CUIのアプリケーション


  • Windows

  • Mac

  • Linux

コンソールアプリケーションもお手の物です。MacやLinuxでは、今やdotnet core を使うのが主流かもしれません(以前はmonoを使いましたが)。


Webアプリケーション


  • ASP.NET Mvc Core

  • ASP.NET Razor(ASP.NET Pages)

  • ASP.NET Blazor

 MacでもLinuxでも動かせますし、またMVCも可能な環境がそろっています。MVC苦手な場合は、.NET 2.0以降より、Razorのみを使うことができるようになり、ページ(Models/Controller/Viewを分ける必要がない)だけでの実装も出来るので、PHPやPerl・ASP(VBScript)など、フレームワークを特段使わないような形で作れますね。一応、MVVMの仕組みっぽいですが、いまいちこのあたりの概念が...。

 今流行りのReactやVue.jsなどのテンプレートも用意されています。(Vueはちょっと特殊な準備が必要)。SPA(Single Page Application)やPWA(Progressive Web Apps)の環境構築も意外に簡単なため、もうPHPに後戻りできません。欠点は、レンタルサーバーでは、ほぼ動作させられないという所でしょうか...。(VPSなりAWSなりで組む必要がありますね。)

 あと、ASP.NET Blazorとは、WebAssemblyを通して実装できるネイティブクライアントアプリの実装形態です。現在はまだプレビュー(試作段階)なので破壊的仕様変更もあるかと思いますが、C#言語でクライアント側のWeb実装が出来ることもあって今注目を浴びています(猫により)。いろいろ試作してみているのですが、Javascript使わずに動的にテキストエリアやDOM操作が行える点はかなり最高です。Javascript、ほとんど不要ですね。唯一の大きな欠点は、デバッガが通らないのでブレイクポイントを設置できないため、結構つらい点があります。いずれ、デバッガーも通るようになるかもしれませんので、それまでは辛抱ですね。

 WebAssemblyとしてコンパイル・実行させることが可能な言語はまだ少ないので、注目の一つではあります。


まとめ

 Windowsアプリケーション開発からMac/Linuxの環境、携帯端末向けからウェブサイトまで、あらゆるアプリケーションの開発が可能になってきた.NETの環境。今ゴタゴタとなってしまっているJavaの環境を皮肉るかのように、いろんな環境でも動作できる環境になりました。

 また、比較的新しい機能が取り入れられ、他の言語でも採用されたり(async/await)、逆に取り入れようとしたり(swiftのオブジェクト非null化)と、頻繁に機能が増えたり変わったりで学習するのは結構難易度が高い言語ではありますが、やっていて楽しいという点でもあり、また将来性のある言語でもあるかと思います。

 今後、ウェブの行く末がネイティブのアプリを超える可能性もあり、WebAssemblyをはじめとしたSPA/PWA環境構築のための言語・環境の一つして活躍していってほしいものです。