Visual C# ステップアップ教室 ～少しでもモダンになるための道標～

# 概要
　私が最初に触った言語は[Hot Soup Processor](http://hsp.tv)でした。ただ、色々苦しい点がありましたので(**お察しください**)、GUIアプリケーションは[Visual C#](https://msdn.microsoft.com/ja-jp/library/dd492171.aspx)に移行しました。
　ただこの言語、快適ではあるのですが何気に**学ぶべきことが多い**です。言語仕様はもちろんのこと、各種ライブラリの使い方をマスターしないとモダンなGUIアプリケーションを作れないという重大な問題が……。
　そこで、後学のため、**最低限必要だと思われる技術**についてザッとまとめました。~~マサカリ大歓迎です~~

※著者の開発遍歴の都合上、UWPやXamarinといった技術についての解説はあまり行いません
※ググっていたところ、既に上位互換に近い記事が出ていて驚きました。参考文献として載せておきます。
　　[[C#][.NET][WPF] WPFと関連知識まとめ - Qiita](https://qiita.com/koara-local/items/c58ca6b83e46b7c6125c)

# 目次
- GUI編
 - WPF
 - XAML
 - MVVM
 - ReactiveProperty
 - その他
- 言語仕様編
 - LINQ
 - async/await
 
# GUI編
## WPF
　ざっくり言うと「Windows用」の「デスクトップアプリ」を作るための「便利な」フレームワークのことです。このカッコ書きが曲者で、

- マルチプラットフォーム用に開発する際は[Xamarin](https://qiita.com/amay077/items/38ee79b3e3e88cf751b9)や[JavaFX](https://qiita.com/tarosa0001/items/05ac653a091b7d1290f9)など他のライブラリ群を使用する
- ストアアプリ開発には[UWP](https://docs.microsoft.com/ja-jp/windows/uwp/get-started/whats-a-uwp)を使用するし、スマホアプリ開発にはXamarinや[Android SDK](https://developer.android.com/studio/index.html?hl=ja)などを使用する
- [WinForms](https://ja.wikipedia.org/wiki/Windows_Forms)でゴリゴリ書いたり、スクリプト言語等でUIを組み立てたい人向けではない

なんですよね。ただ、WPF・~~SilverLight~~・UWP・Xamarin.Formsは、後述する[XAML](https://blogs.msdn.microsoft.com/shozoa/2014/07/23/xaml/)と[MVVM](https://ja.wikipedia.org/wiki/Model_View_ViewModel)を組み合わせて開発を行うのが基本ですので、WPFであらかた慣れておいた方が楽だと思います(主観、と言うより**現在進行形**)。
　WPF開発が概念的にどんな感じかについては、次の資料が一番分かりやすいでしょう。
　　[むずかしくないWPF - Qiita](https://qiita.com/karno/items/f30f661b40d9adec6a6d)
　　[第3回　画面は「XAML」で作る（前編）：連載：Windowsストア・アプリ開発入門 - ＠IT](http://www.atmarkit.co.jp/ait/articles/1310/03/news078.html)

## XAML
　WPFやUWPなどでは、画面設計を「XAML」と呼ばれるXMLライクな言語で開発します。
　WinForms時代と同じく、UIデザイナーを駆使してサクサク開発……は可能ではあるのですが、XAMLの持つ機能(各種コンテナなど)をフルに活かそうとした場合は**大部分を手打ち**することになります(ある程度入力補完されますが)。UIデザイナーでポン付けするとどう不味いかについては、次の記事に掲載しています。
　　[WPFにおけるGUI構築講座 -座標ベタ書きから脱却しよう- - Qiita](https://qiita.com/YSRKEN/items/686068a359866f21f956)

## MVVM
　MVVMは「Model-View-ViewModel」の略称です。特徴としては、データやコマンドが次の図のように流れることでしょうか(出典：[Wikipedia](https://ja.wikipedia.org/wiki/Model_View_ViewModel))。
　Viewが画面の表示周り(WPFだと**XAML**)、Modelが内部ロジック(WPFだと**C#**)、ViewModelが両者の橋渡しをする部分(WPFだと**C#**)ですね。このようにして役割を分担することで、保守性や生産性を高めることを目的にしています。XAMLと同じく、この辺は慣れですね。

![MVVMPattern.png](https://qiita-image-store.s3.amazonaws.com/0/29802/72bf3556-35a7-9e23-40a6-16cb701039f5.png)

　……ただ、VisualStudioで素のプロジェクトを作成した場合は、**全然MVVMを活かせそうにない画面構成にしてくれやがります**。ゆえに[Prism](http://blog.okazuki.jp/entry/2016/07/16/221431)や[Livet](https://qiita.com/Kokudori/items/ab5fcac4b31d7290e630)などのライブラリを導入することによって簡単化することが普通ですが、手打ちしてみたい場合は次の記事を参考にしてみてください。
　　[C#の便利な機能についての備忘録 - Qiita](https://qiita.com/YSRKEN/items/362869c41f562a6fdda0#mvvm)

## ReactiveProperty
　これは、上記MVVMに基いてプログラミングする際に役立つ補助的なライブラリです。どれぐらい便利かについてですが、**使わず書いた版と見比べれば一目瞭然**ですので、それが分かる資料を貼っておきましょう。
　　**自作の全部入りまとめ→[【C#】ReactiveProperty全然分からねぇ！って人向けのFAQ集【修正済】](https://qiita.com/YSRKEN/items/5a36fb8071104a989fb8)**
　　**メンテナーかずきさんによる解説→[ReactiveProperty オーバービュー - かずきのBlog@hatena](http://blog.okazuki.jp/entry/2014/05/07/014133)**
　また、ReactivePropertyとPrismを併用した際はどういったコードになるかの例も貼っておきます。
　　[PrismとReactivePropertyで簡単MVVM！ - Qiita](https://qiita.com/hiki_neet_p/items/e381c687b0644c0e4978)

## その他
　WPFだとWinForms時代のコントロール(ボタンやテキストボックスなど)が概ねそのまま使えますが、なぜか[Chartコントロール](https://msdn.microsoft.com/ja-jp/library/kx2ttx0a.aspx)は移植されていません。一応`<WindowsFormsHost>`で囲めば[ChartコントロールをWPFで使用できる](https://qiita.com/nocd5/items/064a783240c1e8590169)のですが、一般には[OxyPlot](http://www.oxyplot.org)や[LiveCharts](LiveCharts)など外部のライブラリを導入することになると思います。
　　[OxyPlotでグラフを表示させる際にハマったことまとめ - Qiita](https://qiita.com/YSRKEN/items/04cb879bf7f19cd1567c)
　また、WPFの特徴の一つとして、「デザインを作り込みやすい(リッチUIを組みやすい)」ということもあります。普通にXAMLなどで手作りしてもいいですし、[Material Design In XAML Toolkit](https://github.com/ButchersBoy/MaterialDesignInXamlToolkit)といった強力なライブラリもあります。詳しくは次の記事をどうぞ。
　　[neue cc - Material Design In XAML Toolkitでお手軽にWPFアプリを美しく](http://neue.cc/2015/09/10_515.html)

# 言語仕様編
　**まあこのサイト読んでおけば全部済むよね！**
　　[++C++; // 未確認飛行 C](http://ufcpp.net/study/csharp/sp3_linq.html)
　というわけで以下の記述は蛇足です。お疲れ様でした……とは言いたくありませんので概要だけでも読んで下さいな。
## LINQ
　LINQとは[某アイドルグループ](http://loveinq.com)……ではなく、「Language INtegrated Query」というC#3.0で搭載された機能のことです。ノリとしては、[MapReduce](https://www.slideshare.net/n3104/mapreduce-7587216)や[SQL](http://postd.cc/a-beginners-guide-to-sql/)に近い感じです。
　　[LINQ - C# によるプログラミング入門 _ ++C++; // 未確認飛行 C](http://ufcpp.net/study/csharp/sp3_linq.html)
　つまり、配列などのデータ群に対し「検索/抽出」「変換」などの処理をサクッと行えるようにするためのライブラリと考えましょう。具体的には、次の`func1()`が`func2()`まで短くなります。

```csharp
//　学生の一覧から、身長が170cm以上の者達の名前の一覧を作成する
List<string> func1(List<Student> data){
    List<string> output;
    foreach(var student in data){
        if(student.Height >= 170){
            output.Add(student.Name);
        }
    }
    return output;
}
// 同上(LINQ版)
List<string> func2(List<Student> data){
    return data.Where(s => s.Height >= 170).Select(s => s.Name).ToList();
}
```
　LINQのメリットは短さだけでなく、「遅延評価が使える」「並列処理もできる」「メソッドチェーンが気持ちいい」などもありますが、より詳しく知りたい人は次の記事が参考になるでしょう。
　　[はじめての LINQ - Qiita](https://qiita.com/nskydiving/items/c9c47c1e48ea365f8995)

## async/await
　こちらはC# 5.0で実装された機能の一つです。端的に言いますと、これを使えば**非同期処理を書くのが超楽になります**。
　　[非同期メソッド - C# によるプログラミング入門 : ++C++; // 未確認飛行 C](http://ufcpp.net/study/csharp/sp5_async.html)

　……「非同期処理」を知らない人のために補足しますと、同期処理ではプログラムが「上から下」の順番通りに動作します。当然だと思うかもしれませんが、これだと困ることは**稀によくあります**。

```csharp
// 処理1
func1();
// 処理2(時間がかかる処理)
func2();
// 処理3
func3();
```

　上記のコードをそのまま実行した場合、プログラムは`func2()`を処理する段階で足踏みすることになります。すると、`func3()`だけでなく、「それ以降の処理(コードブロックを抜けた後のGUIロジックなど)」がなかなか実行されません。つまり、GUIアプリケーションだと**画面が白く固まって入力を受け付けない**という不都合な事態になります。せめて中断ボタンを効かせたり、途中経過を表示したりしたいですよね？
　そこで非同期処理です。上記をawaitを用いて書くとこんな風になります。

```csharp
// 処理1
func1();
// 処理2(時間がかかる処理)
// 非同期処理する関数では、関数名の末尾にAsyncを付けるのが慣例
await func2Async();
// 処理3
func3();
```

　この際、プログラムとしては`func1()`を実行した後、`func2Async()`を飛ばしてコードブロックを抜け、「それ以降の処理」が実行されます。飛ばしたと言っても無視しているわけではなく、別スレッドで`func2Async()`を処理し、終了次第`func3()`以降が実行される……といった流れになります。
　これにより、「中断ボタン」や「途中経過」など他の処理にCPU時間を回す余裕ができますので、画面が白く固まらずに済みます。
　また、同期処理と違い、「全ての完了を待たなくても次の処理ができる」ので、例えば「ダウンロードしたコンテンツを逐一表示していく」といった処理も可能になります。

　非同期処理自体はC#4.0以前でも書けましたが、ハッキリ言って**面倒臭い**ものでした。それがasync/awaitにより大幅に書きやすくなったのは革命的です。今では[JavaScript](https://qiita.com/kiyodori/items/da434d169755cbb20447)など、他の言語にもasync/awaitの思想は伝播しているようです。
　ただ、書きやすくなったとは言っても、使いこなすには練習が必要です。ということで参考資料を数点貼っておきます。
　　[Taskを極めろ！async/await完全攻略 - Qiita](https://qiita.com/acple@github/items/8f63aacb13de9954c5da)
　　[技術解説 – 非同期 – kekyoの丼](https://www.kekyo.net/async)