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


概要

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

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

目次

  • GUI編
    • WPF
    • XAML
    • MVVM
    • ReactiveProperty
    • その他
  • 言語仕様編
    • LINQ
    • async/await

GUI編

WPF

 ざっくり言うと「Windows用」の「デスクトップアプリ」を作るための「便利な」フレームワークのことです。このカッコ書きが曲者で、

  • マルチプラットフォーム用に開発する際はXamarinJavaFXなど他のライブラリ群を使用する
  • ストアアプリ開発にはUWPを使用するし、スマホアプリ開発にはXamarinやAndroid SDKなどを使用する
  • WinFormsでゴリゴリ書いたり、スクリプト言語等でUIを組み立てたい人向けではない

なんですよね。ただ、WPF・SilverLight・UWP・Xamarin.Formsは、後述するXAMLMVVMを組み合わせて開発を行うのが基本ですので、WPFであらかた慣れておいた方が楽だと思います(主観、と言うより現在進行形)。
 WPF開発が概念的にどんな感じかについては、次の資料が一番分かりやすいでしょう。
  むずかしくないWPF - Qiita
  第3回 画面は「XAML」で作る(前編):連載:Windowsストア・アプリ開発入門 - @IT

XAML

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

MVVM

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

 ……ただ、VisualStudioで素のプロジェクトを作成した場合は、全然MVVMを活かせそうにない画面構成にしてくれやがります。ゆえにPrismLivetなどのライブラリを導入することによって簡単化することが普通ですが、手打ちしてみたい場合は次の記事を参考にしてみてください。
  C#の便利な機能についての備忘録 - Qiita

ReactiveProperty

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

その他

 WPFだとWinForms時代のコントロール(ボタンやテキストボックスなど)が概ねそのまま使えますが、なぜかChartコントロールは移植されていません。一応<WindowsFormsHost>で囲めばChartコントロールをWPFで使用できるのですが、一般にはOxyPlotLiveChartsなど外部のライブラリを導入することになると思います。
  OxyPlotでグラフを表示させる際にハマったことまとめ - Qiita
 また、WPFの特徴の一つとして、「デザインを作り込みやすい(リッチUIを組みやすい)」ということもあります。普通にXAMLなどで手作りしてもいいですし、Material Design In XAML Toolkitといった強力なライブラリもあります。詳しくは次の記事をどうぞ。
  neue cc - Material Design In XAML Toolkitでお手軽にWPFアプリを美しく

言語仕様編

 まあこのサイト読んでおけば全部済むよね!
  ++C++; // 未確認飛行 C
 というわけで以下の記述は蛇足です。お疲れ様でした……とは言いたくありませんので概要だけでも読んで下さいな。

LINQ

 LINQとは某アイドルグループ……ではなく、「Language INtegrated Query」というC#3.0で搭載された機能のことです。ノリとしては、MapReduceSQLに近い感じです。
  LINQ - C# によるプログラミング入門 _ ++C++; // 未確認飛行 C
 つまり、配列などのデータ群に対し「検索/抽出」「変換」などの処理をサクッと行えるようにするためのライブラリと考えましょう。具体的には、次のfunc1()func2()まで短くなります。

// 学生の一覧から、身長が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

async/await

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

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

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

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

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

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

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