30
Introduction to NotifyPropertyChangedGenerator Yoshifumi Kawai - @neuecc 2015/05/30 めとべや東京 #8

Introduction to NotifyPropertyChangedGenerator

Embed Size (px)

Citation preview

Introduction toNotifyPropertyChangedGenerator

Yoshifumi Kawai - @neuecc2015/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)));

}}

}

FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU-

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時代は既に来ている