Introduction to
NotifyPropertyChangedGenerator
Yoshifumi Kawai - @neuecc
2015/05/30 めとべや東京 #8
Self Introduction
@仕事
株式会社グラニ 取締役CTO
最先端C#によるサーバー/クライアント大統一ゲーム開発
@個人活動
Microsoft MVP for .NET(C#)
Web http://neue.cc/ Twitter @neuecc
最近はUnity用Rx、UniRxが個人プロジェクトとしてアクティブ
2015-06-19にUniRx勉強会やります
https://unirx.doorkeeper.jp/events/25218
NotifyPropertyChanged HELL
public class PersonViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string name;
public string Name
{
get { return this.name; }
set
{
if (this.name == value) return;
this.name = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
}
}
private int age;
public int Age
{
get { return this.age; }
set
{
if (this.age == value) return;
this.age = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Age)));
}
}
}
FFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUUUUUU-
public class PersonViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string name;
public string Name
{
get { return this.name; }
set
{
if (this.name == value) return;
this.name = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
}
}
private int age;
public int Age
{
get { return this.age; }
set
{
if (this.age == value) return;
this.age = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Age)));
}
}
}
コードスニペットは全てを解決しない
1. コピペバビリティの低さ
生成量が多くて修正対象がおおいため、コー
ドスニペット経由以外での作成が不可
2. ようするに修正耐性が低い
名前の変更等でも修正箇所が多くなったりする
(nameofで若干マシになったけど全然足りない)
3. そもそも生成コード量が多くてノイズと
なっていて見通しが悪くなる
(プロパティ毎にregionで更に見通し悪く)
#ない
Roslyn Samples
ImplementNotifyPropertyChanged
Demo...
Roslyn Sample : ImplementNotifyPropertyChanged
これじゃない感
ただのSampleで実用レベルではない…… #知ってた
public class PersonViewModel : INotifyPropertyChanged
{
private string name;
public string Name
{
get
{
return name;
}
set
{
SetProperty(ref name, value, "Name");
}
}
private int age;
public int Age
{
get
{
return age;
}
set
{
SetProperty(ref age, value, "Age");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void SetProperty<T>(ref T field, T value, string name)
{
if (!EqualityComparer<T>.Default.Equals(field, value))
{
field = value;
生成が少々短縮化されただけで、コー
ドスニペットの抱えていた3つの問題を
(生成結果が同じなので当然ですが)
何も解決できていない
NotifyPropertyChangedGenerator
Demo...
NotifyPropertyChangedGenerator
NotifyPropertyChangedGenerator
Roslyn用Analyzerとしての実装しNuGet配布
https://github.com/neuecc/NotifyPropertyChangedGenerator
PM> Install-Package NotifyPropertyChangedGenerator
Visual Studio 2015があれば依存なし
今すぐどのプロジェクトにも使える
DLL参照もない
.NET Framework 3.5でもUniversal AppでもUnityでも使える
[Notify]を付与した状態で変更通知プロパ
ティが生成されていない場合
コンパイラエラーとして通知
エラー出てるとこからCtrl+.で
発火する
プロパティ部分は一行をキープ
(自動実装プロパティと同等の
見やすさ)
自動生成コードは、コードの末尾にまとめてしま
うことによって、コード本体はクリーンに保てる
(コードスニペットと違ってAnalyzerなら生成箇所
が自由という特性がある)
継承不要な、POMO(Plain Old
MVVM Object)の実現
NameをFullNameに変更、生成さ
れていないことを検出しすぐコン
パイルエラー+差分生成可能
vs PostSharp/Fody
ビルド後IL書き換えによる綺麗な埋め込み
コードは非常に綺麗になる
が、ビルドプロセスの複雑化+デバッガビリティの低下がある
Analyzerは現実解
Visual Studio(2015)との完全な統合と配布容易性(NuGetで全部入る)
コード生成なのでデバッグへの影響は全くない
記述時のリアルタイムコンパイラエラー/警告は十分以上に強力
What is Analyzer?
C# 6.0 is...
Initializers for auto-properties
Getter-only auto-properties
Expression-bodied function members
Using static
Null-conditional operators
String interpolation
nameof expressions
Index initializers
Exception filters
Await in catch and finally blocks
小粒なのばっか……
そういうのじゃなくて、大事なのは?
C# 6.0 = Roslyn!
RoslynこそがC# 6.0の最大の真価では?
しかし別に小粒な機能が実装しやすくなったとかdoudemoii
そんなんじゃないだろう!
Roslyn = Analyzer
今のところユーザーが感じられるメリットとしては。
C# 6.0じゃないだろ、とかそういう細かいことは置いておく
Analyerは小粒な機能などではない、非常に強力な機能追加
Analyzer
= Better StyleCop
Analyzer
= Better StyleCop
ではない
Analyzer =
Compiler Extension
+
Code Generator
コンパイラ拡張+コード生成
コード生成
解析よりもむしろメインなぐらい、しかし勿論解析があってこそ
のコード生成というセットなところが重要
Library + Analyzer = Code Aware Libraries
ライブラリとAnalyzerは同梱可(NuGetでプロジェクト単位に)
ライブラリ固有の生成や警告、ガイドなどをAnalyzerを使って
ユーザーに示して、より人に優しいライブラリへ
というのがVS2015以降のあり方かもしれない
Conclusion
まとめ
時代はRoslyn
時代はPOMO(Plain Old MVVM Object)
(勿論)既存のMVVMライブラリと共存できます
NotifyPropertyChangedGenerator
https://github.com/neuecc/NotifyPropertyChangedGenerator
PM> Install-Package NotifyPropertyChangedGenerator
今すぐ、どのプロジェクトにも即導入できます!
刺身たんぽぽから卒業しよう、VS2015時代は既に来ている

Introduction to NotifyPropertyChangedGenerator