Submit Search
C#メタプログラミング概略 in 2021
Download as PPTX, PDF
0 likes
1,221 views
A
Atsushi Nakamura
本項はC# Tokyo オンライン LT 大会 2021/01にて発表した「C#メタプログラミング概略 in 2021」の発表資料です。
Technology
Read more
1 of 49
Download now
Download to read offline
1
2
Most read
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
More Related Content
PDF
ゲーム開発者のための C++11/C++14
Ryo Suzuki
PPTX
C#とILとネイティブと
信之 岩永
PDF
MagicOnion入門
torisoup
PDF
ドメイン駆動設計 ( DDD ) をやってみよう
増田 亨
PDF
【Unite Tokyo 2019】Understanding C# Struct All Things
UnityTechnologiesJapan002
PDF
Riderはいいぞ!
UnityTechnologiesJapan002
PDF
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
Yoshifumi Kawai
PPTX
async/await のしくみ
信之 岩永
ゲーム開発者のための C++11/C++14
Ryo Suzuki
C#とILとネイティブと
信之 岩永
MagicOnion入門
torisoup
ドメイン駆動設計 ( DDD ) をやってみよう
増田 亨
【Unite Tokyo 2019】Understanding C# Struct All Things
UnityTechnologiesJapan002
Riderはいいぞ!
UnityTechnologiesJapan002
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
Yoshifumi Kawai
async/await のしくみ
信之 岩永
What's hot
(20)
PDF
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
Unity Technologies Japan K.K.
ODP
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
pospome
PDF
規格書で読むC++11のスレッド
Kohsuke Yuasa
PDF
今日からできる!簡単 .NET 高速化 Tips
Takaaki Suzuki
PDF
できる!並列・並行プログラミング
Preferred Networks
PDF
Tackling Complexity
Yoshitaka Kawashima
PDF
[CEDEC 2021] 運用中タイトルでも怖くない! 『メルクストーリア』におけるハイパフォーマンス・ローコストなリアルタイム通信技術の導入事例
Naoya Kishimoto
PPTX
世界一わかりやすいClean Architecture
Atsushi Nakamura
PDF
IL2CPPに関する軽い話
Wooram Yang
PPTX
SPAセキュリティ入門~PHP Conference Japan 2021
Hiroshi Tokumaru
PDF
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
JustSystems Corporation
PDF
Assembly Definition あれやこれ
NakanoYosuke1
PDF
それはYAGNIか? それとも思考停止か?
Yoshitaka Kawashima
PDF
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
Genya Murakami
PPTX
Python / BlueprintによるUnreal Engineの自動化 / GTMF2019
Game Tools & Middleware Forum
PPTX
C#や.NET Frameworkがやっていること
信之 岩永
PDF
Constexprとtemplateでコンパイル時にfizz buzz
京大 マイコンクラブ
PDF
ソーシャルゲームのためのデータベース設計
Yoshinori Matsunobu
PPTX
猫でも分かるUMG
エピック・ゲームズ・ジャパン Epic Games Japan
PPTX
プログラマが欲しい仕様書とは
Katsutoshi Makino
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
Unity Technologies Japan K.K.
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
pospome
規格書で読むC++11のスレッド
Kohsuke Yuasa
今日からできる!簡単 .NET 高速化 Tips
Takaaki Suzuki
できる!並列・並行プログラミング
Preferred Networks
Tackling Complexity
Yoshitaka Kawashima
[CEDEC 2021] 運用中タイトルでも怖くない! 『メルクストーリア』におけるハイパフォーマンス・ローコストなリアルタイム通信技術の導入事例
Naoya Kishimoto
世界一わかりやすいClean Architecture
Atsushi Nakamura
IL2CPPに関する軽い話
Wooram Yang
SPAセキュリティ入門~PHP Conference Japan 2021
Hiroshi Tokumaru
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
JustSystems Corporation
Assembly Definition あれやこれ
NakanoYosuke1
それはYAGNIか? それとも思考停止か?
Yoshitaka Kawashima
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
Genya Murakami
Python / BlueprintによるUnreal Engineの自動化 / GTMF2019
Game Tools & Middleware Forum
C#や.NET Frameworkがやっていること
信之 岩永
Constexprとtemplateでコンパイル時にfizz buzz
京大 マイコンクラブ
ソーシャルゲームのためのデータベース設計
Yoshinori Matsunobu
猫でも分かるUMG
エピック・ゲームズ・ジャパン Epic Games Japan
プログラマが欲しい仕様書とは
Katsutoshi Makino
Ad
Similar to C#メタプログラミング概略 in 2021
(20)
PDF
C#でもメタプログラミングがしたい!!
TATSUYA HAYAMIZU
PPTX
メタな感じのプログラミング(プロ生 + わんくま 071118)
Tatsuya Ishikawa
PPTX
Eclipse modeling projectの概要
Shintaro Hosoai
PDF
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
Yoshifumi Kawai
PDF
Object-Functional Analysis and Design : 次世代モデリングパラダイムへの道標
Tomoharu ASAMI
PDF
Scrum alliance regional gathering tokyo 2013 pub
グロースエクスパートナーズ株式会社/Growth xPartners Incorporated.
PPT
メタプログラミングって何だろう
Kota Mizushima
PDF
2010 icse-an analysis of the variability in forty preprocessor-based software...
n-yuki
PDF
Object-Funcational Analysis and design
Tomoharu ASAMI
PPTX
GoF デザインパターン 2009
miwarin
PDF
C#勉強会 ~ C#9の新機能 ~
Fujio Kojima
PDF
JavaWorld Day 2009 Scala
Tomoharu ASAMI
PDF
C++ Template Meta Programming の紹介@社内勉強会
Akihiko Matuura
PDF
テンプレートメタプログラミング as 式
digitalghost
PDF
Clojure
Uehara Junji
PDF
C# から java へのプログラム移植で体験したtddの効果は?
Shinichi Hirauchi
PDF
関数モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第8回】
Tomoharu ASAMI
PDF
Scalable Generator: Using Scala in SIer Business (ScalaMatsuri)
TIS Inc.
PDF
C++ Template Metaprogramming
Akira Takahashi
PPTX
テストの視点からのモデリング(公開用) #wacate
Kinji Akemine
C#でもメタプログラミングがしたい!!
TATSUYA HAYAMIZU
メタな感じのプログラミング(プロ生 + わんくま 071118)
Tatsuya Ishikawa
Eclipse modeling projectの概要
Shintaro Hosoai
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
Yoshifumi Kawai
Object-Functional Analysis and Design : 次世代モデリングパラダイムへの道標
Tomoharu ASAMI
Scrum alliance regional gathering tokyo 2013 pub
グロースエクスパートナーズ株式会社/Growth xPartners Incorporated.
メタプログラミングって何だろう
Kota Mizushima
2010 icse-an analysis of the variability in forty preprocessor-based software...
n-yuki
Object-Funcational Analysis and design
Tomoharu ASAMI
GoF デザインパターン 2009
miwarin
C#勉強会 ~ C#9の新機能 ~
Fujio Kojima
JavaWorld Day 2009 Scala
Tomoharu ASAMI
C++ Template Meta Programming の紹介@社内勉強会
Akihiko Matuura
テンプレートメタプログラミング as 式
digitalghost
Clojure
Uehara Junji
C# から java へのプログラム移植で体験したtddの効果は?
Shinichi Hirauchi
関数モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第8回】
Tomoharu ASAMI
Scalable Generator: Using Scala in SIer Business (ScalaMatsuri)
TIS Inc.
C++ Template Metaprogramming
Akira Takahashi
テストの視点からのモデリング(公開用) #wacate
Kinji Akemine
Ad
More from Atsushi Nakamura
(19)
PPSX
Settings SyncとCodespaceで体験する新世代へのパラダイムシフト
Atsushi Nakamura
PPTX
Unicodeで半角全角を扱うAmbiguous(曖昧さ)とUncertainty(不確実性)の恐怖
Atsushi Nakamura
PPTX
世界一わかりやすいClean Architecture - DroidKaigiバージョン
Atsushi Nakamura
PPTX
世界一わかりやすいClean Architecture release-preview
Atsushi Nakamura
PPTX
世界一わかりやすいClean Architecture alpha-1
Atsushi Nakamura
PPTX
Visual Studio 2019で始める「WPF on .NET Core 3.0」開発
Atsushi Nakamura
PPTX
Desktop app dev strategy for .net core 3.0
Atsushi Nakamura
PPTX
継続的にテスト可能な設計を考える
Atsushi Nakamura
PPTX
継続的にテスト可能な設計を考える ベータ版
Atsushi Nakamura
PPTX
α版 継続的にテスト可能な設計を考える
Atsushi Nakamura
PDF
App center analyticsを使い倒そう
Atsushi Nakamura
PPTX
Old:App center analyticsを使い倒そう
Atsushi Nakamura
PPTX
Xamarin.forms navigation overview
Atsushi Nakamura
PPTX
App center analyticsを使い倒そう
Atsushi Nakamura
PPTX
「関心の分離」と「疎結合」 ソフトウェアアーキテクチャのひとかけら
Atsushi Nakamura
PPTX
Blue monkey architecture overview
Atsushi Nakamura
PPTX
Xamarin Dev days 2 xamarin.forms ja
Atsushi Nakamura
PPTX
Why prism for xamarin.forms
Atsushi Nakamura
PPTX
Enterpriseから見たXamarinの可能性
Atsushi Nakamura
Settings SyncとCodespaceで体験する新世代へのパラダイムシフト
Atsushi Nakamura
Unicodeで半角全角を扱うAmbiguous(曖昧さ)とUncertainty(不確実性)の恐怖
Atsushi Nakamura
世界一わかりやすいClean Architecture - DroidKaigiバージョン
Atsushi Nakamura
世界一わかりやすいClean Architecture release-preview
Atsushi Nakamura
世界一わかりやすいClean Architecture alpha-1
Atsushi Nakamura
Visual Studio 2019で始める「WPF on .NET Core 3.0」開発
Atsushi Nakamura
Desktop app dev strategy for .net core 3.0
Atsushi Nakamura
継続的にテスト可能な設計を考える
Atsushi Nakamura
継続的にテスト可能な設計を考える ベータ版
Atsushi Nakamura
α版 継続的にテスト可能な設計を考える
Atsushi Nakamura
App center analyticsを使い倒そう
Atsushi Nakamura
Old:App center analyticsを使い倒そう
Atsushi Nakamura
Xamarin.forms navigation overview
Atsushi Nakamura
App center analyticsを使い倒そう
Atsushi Nakamura
「関心の分離」と「疎結合」 ソフトウェアアーキテクチャのひとかけら
Atsushi Nakamura
Blue monkey architecture overview
Atsushi Nakamura
Xamarin Dev days 2 xamarin.forms ja
Atsushi Nakamura
Why prism for xamarin.forms
Atsushi Nakamura
Enterpriseから見たXamarinの可能性
Atsushi Nakamura
C#メタプログラミング概略 in 2021
1.
Copyright 2020 @nuits_jp C#メタプログラミング概略
in 2021 Atsushi Nakamura
2.
Copyright 2020 @nuits_jp
Slide 2 C# 9.0と合わせて、Source Generatorがリリースされました。※ それに伴い、メタプログラミングが活性化しているように見えます。 ※厳密にはC#9.0世代のプラットフォームで実現しているが、C#9.0の 機能ではない? https://docs.microsoft.com/ja-jp/dotnet/csharp/whats-new/csharp-9 実際、C#7.3(netstandard2.0世代)などを明示的に指定しても利用できる Background
3.
Copyright 2020 @nuits_jp
Slide 3 そこで今回は
4.
Copyright 2020 @nuits_jp
Slide 4 C#で利用可能な代表的なメタプログラミング手法について • どういったものが存在し • どういう時に何をつかえばいいのか? その大枠を整理してみました。 Today's Goal
5.
Copyright 2020 @nuits_jp
Slide 5 Attention!
6.
Copyright 2020 @nuits_jp
Slide 6 本日の内容は、発表のために改めて調査・整理したものです。 私自身、普段あまり接点のない技術もありますので、抜け漏れ誤りがあ るかもしれません。 また、多分に主観が含まれています。 お気づきの点があれば、ぜひ気軽に「やさしく」ご指摘ください。 Attention!
7.
Copyright 2020 @nuits_jp C#
Metaprogramming Overview About Me
8.
Copyright 2020 @nuits_jp
Slide 8 About Me 中村 充志 / Atsushi Nakamura • リコージャパン株式会社 所属 • Enterprise(おもに金融)系SIerのITアーキテクト • 「持続可能なソフトウェア」の探求がライフワーク • 2021年の目標 1. いろいろハンズオン開催したい xUnit、FluentAssertions、Moq、TDD 2. 構成管理フレンドリーなERモデリングツール作成 • Blog http://www.nuits.jp https://zenn.dev/nuits_jp • Twitter @nuits_jp
9.
Copyright 2020 @nuits_jp C#
Metaprogramming Overview What is metaprogramming?
10.
Copyright 2020 @nuits_jp
Slide 10 What is metaprogramming? メタプログラミングとは何か? Wikipediaより “プログラミング技法の一種で、ロジックを直接コーディングす るのではなく、あるパターンをもったロジックを生成する高位ロ ジックによってプログラミングを行う方法、またその高位ロジッ クを定義する方法のこと。” https://ja.wikipedia.org/wiki/メタプログラミング
11.
Copyright 2020 @nuits_jp
Slide 11 • データベースのテーブル定義からクラスを生成する • クラス構造を解析してJSONへシリアライズ/デシリアライズする • シリアライズ/デシリアライズする際に、フィールドやプロパティに 属性を指定することで制御する つまり 「メタデータをもとに、プログラムを生成するプログラミング」 具体例
12.
Copyright 2020 @nuits_jp
Slide 12 .NETのメタプログラミング技術(多分もっとある) 1. CodeDOM 2. Roslyn(ここではNuGet上のライブラリ利用のこと) 3. Reflection 4. Reflection.Emit 5. ExpressionTree 6. T4TextTemplates 7. Source Generator ← New!! 8. Fody / Mono.Cecil メタプログラミング
13.
Copyright 2020 @nuits_jp
Slide 13 本日扱う.NETのメタプログラミング技術 1. CodeDOM 2. Roslyn(ここではNuGet上のライブラリ利用のこと) 3. Reflection 4. Reflection.Emit 5. ExpressionTree 6. T4TextTemplates 7. Source Generator ← New!! 8. Fody / Mono.Cecil メタプログラミング
14.
Copyright 2020 @nuits_jp
Slide 14 本日扱う.NETのメタプログラミング技術 1. Reflection 2. ExpressionTree 3. T4TextTemplates 4. Source Generator 5. Fody / Mono.Cecil メタプログラミング
15.
Copyright 2020 @nuits_jp
Slide 15 どういう時に、何を使えばいいの?
16.
Copyright 2020 @nuits_jp
Slide 16 主要なユーザーストーリーパターンで分類すると、つぎのラインでわけ ることができる 1. Reflection 2. ExpressionTree 3. T4TextTemplates 4. Fody / Mono.Cecil 5. Source Generator メタプログラミング
17.
Copyright 2020 @nuits_jp
Slide 17 主要なユーザーストーリーパターンで分類すると、つぎのラインでわけ ることができる 1. Reflection 2. ExpressionTree 3. T4TextTemplates 4. Fody / Mono.Cecil 5. Source Generator メタプログラミング 自分自身のためのメタプログラミング
18.
Copyright 2020 @nuits_jp
Slide 18 主要なユーザーストーリーパターンで分類すると、つぎのラインでわけ ることができる 1. Reflection 2. ExpressionTree 3. T4TextTemplates 4. Fody / Mono.Cecil 5. Source Generator メタプログラミング 自分自身のためのメタプログラミング 自分を含む誰かのためのメタプログラミング
19.
Copyright 2020 @nuits_jp
Slide 19 項目 内容 実現技術 • Reflection • ExpressionTree 具体例 • Dapper • JSON⇔オブジェクト変換ライブラリなど 利用タイミング 実行時 説明 サードパーティライブラリ(Dapper)などが、機能提供を実現するために、内部で メタプログラミングを利用しているパターン。 SQLの実行結果をオブジェクトに詰めたり、その逆を実現するために、動的にメタ モデルを解析し、メンバーの値を取得したり設定したりするのに利用する。 自分自身のためのメタプログラミング
20.
Copyright 2020 @nuits_jp
Slide 20 項目 内容 実現技術 • T4Template • Source Generator • Fody / Mono.Cecil 具体例 • PropertyChanged.Fody • UnitGenerator 利用タイミング 実行前(詳細は個別に異なる) 説明 前述の例に限定されず、使用可能な用途が広い。誰かには自分も含まれる。 現時点では、第三者が利用する定型的な実装(ボイラーコード)の自動生成に利用 されていることが多い。 WPFなどにINotifyPropertyChanged実装を提供するPropertyChanged.Fody。 ビジネスロジックにバリューオブジェクトを扱うための定型的な実装を提供する UnitGeneratorなどが存在する。 ただし今後は、Dapperなどが自分で利用するコードのためにSourceGeneratorを利 用すると言ったケースが増えてくるのではないかと思われる。早いので。 誰かのためのメタプログラミング
21.
Copyright 2020 @nuits_jp C#
Metaprogramming Overview Implementation example
22.
Copyright 2020 @nuits_jp
Slide 22 本日のお題 Equalsのオーバーライドをサポートするライブラリを作成する。 値の比較はIdentifier属性の宣言されたプロパティで行う。 制限事項 • Identifier属性は1クラス1プロパティにしかない前提とする • 対象はint型のみサポート • 非Genericなクラスにのみ対応すればよい(Generic、struct非対応) • GetHashCodeの実装は割愛する https://github.com/nuitsjp/MetaprogrammingOverviewIn2021
23.
Copyright 2020 @nuits_jp
Slide 23 以下のコードと同じ振る舞いを、各メタプログラミング技術で実装する。 実装例 public class Customer { public int Code { get; set; } public override bool Equals(object other) { if (other is Customer customer) { return Code.Equals(customer.Code); } return false; } }
24.
Copyright 2020 @nuits_jp
Slide 24 Reflection
25.
Copyright 2020 @nuits_jp
Slide 25 1. 圧倒的に簡単 2. 圧倒的に遅い 上記のような特徴があるため、速度がそれほど重要にならない、一度だ け実行できればよい、何らかの処理を自動化するためのツールなどで使 い勝手が良い。 Reflectionの特徴
26.
Copyright 2020 @nuits_jp
Slide 26 No. 実装 実行時間 1 Not metaprogramming 2.798 ns 2 Reflection 2,891.742 ns 3 Reflection with Cache 4 ExpressionTree 5 ExpressionTree with Cache 6 T4Template 7 Source Generator 8 Fody ざっと1,000倍! (とは言え0.002ミリ秒)
27.
Copyright 2020 @nuits_jp
Slide 27 Reflection with Cache
28.
Copyright 2020 @nuits_jp
Slide 28 No. 実装 実行時間 1 Not metaprogramming 2.798 ns 2 Reflection 2,891.742 ns 3 Reflection with Cache 214.812 ns 4 ExpressionTree 5 ExpressionTree with Cache 6 T4Template 7 Source Generator 8 Fody Reflection with Cache
29.
Copyright 2020 @nuits_jp
Slide 29 • 全体の処理の90%を占めるコードを回避できる • 繰り返し実行すればするほど効果が高い • StaticType Cachingパターンがハマりやすい Reflection with Cache
30.
Copyright 2020 @nuits_jp
Slide 30 ExpressionTree
31.
Copyright 2020 @nuits_jp
Slide 31 No. 実装 実行時間 1 Not metaprogramming 2.798 ns 2 Reflection 2,891.742 ns 3 Reflection with Cache 214.812 ns 4 ExpressionTree 85,835.928 ns 5 ExpressionTree with Cache 6 T4Template 7 Source Generator 8 Fody ExpressionTree Compileが非常に遅い
32.
Copyright 2020 @nuits_jp
Slide 32 ExpressionTree with Cache
33.
Copyright 2020 @nuits_jp
Slide 33 No. 実装 実行時間 1 Not metaprogramming 2.798 ns 2 Reflection 2,891.742 ns 3 Reflection with Cache 214.812 ns 4 ExpressionTree 85,835.928 ns 5 ExpressionTree with Cache 7.914 ns 6 T4Template 7 Source Generator 8 Fody ExpressionTree with Cache
34.
Copyright 2020 @nuits_jp
Slide 34 • Notメタプログラミングと、おおむね同等といってよい (nsの世界なので) • ExpressionTreeはキャッシングとセット • キャッシングしないならReflectionでいい • このため型変換系(ORMや通信)のライブラリで使い勝手が良い • やはりStaticType Cachingパターンがハマりやすい ExpressionTree with Cache
35.
Copyright 2020 @nuits_jp
Slide 35 T4Template
36.
Copyright 2020 @nuits_jp
Slide 36 No. 実装 実行時間 1 Not metaprogramming 2.798 ns 2 Reflection 2,891.742 ns 3 Reflection with Cache 214.812 ns 4 ExpressionTree 85,835.928 ns 5 ExpressionTree with Cache 7.914 ns 6 T4Template 2.251 ns 7 Source Generator 8 Fody T4Template
37.
Copyright 2020 @nuits_jp
Slide 37 • 速度は非メタプログラミングと完全に同等(当たり前) • ちょっと癖がある • 本来生成コードは構成管理したくない • レビューやテスト(の特にカバレージチェック)に悪影響 • コード生成する対象コードが増えても、自動生成されない点に特 に注意(削除時は生成コードを一度削除しないとダメ?) • ライブラリとして再配布する場合「利用者が」理解して使う必要有 • IDE依存でCI/CD時に生成は大変(VS、VS for Max、Riderが対応) • でも複雑なコード生成も、すごく簡単(多分一番簡単) T4Template
38.
Copyright 2020 @nuits_jp
Slide 38 Source Generator
39.
Copyright 2020 @nuits_jp
Slide 39 No. 実装 実行時間 1 Not metaprogramming 2.798 ns 2 Reflection 2,891.742 ns 3 Reflection with Cache 214.812 ns 4 ExpressionTree 85,835.928 ns 5 ExpressionTree with Cache 7.914 ns 6 T4Template 2.251 ns 7 Source Generator 2.259 ns 8 Fody Source Generator
40.
Copyright 2020 @nuits_jp
Slide 40 • やはり速度は非メタプログラミングと完全に同等(当たり前) • ソースはメモリ展開されてコンパイルされる • でもデバッグはできちゃう • そのため利用者に「理解を求める」必要がなく再配布しやすい • 上記の理由から、今後例えばDapperやJSON変換のようなライブラリ などで、型変換コードがSource Generatorへ移行していく可能性があ る?しらんけど・・・ • Analyzerとの相性も良く、利用者に使いやすいものを作りやすい • 実は生成コードのテンプレートにT4がすごく使いやすい • IDE非依存なので、CI/CDなんかでも使いやすい Source Generator
41.
Copyright 2020 @nuits_jp
Slide 41 Fody
42.
Copyright 2020 @nuits_jp
Slide 42 No. 実装 実行時間 1 Not metaprogramming 2.798 ns 2 Reflection 2,891.742 ns 3 Reflection with Cache 214.812 ns 4 ExpressionTree 85,835.928 ns 5 ExpressionTree with Cache 7.914 ns 6 T4Template 2.251 ns 7 Source Generator 2.259 ns 8 Fody 2.584 ns Fody
43.
Copyright 2020 @nuits_jp
Slide 43 • 他と比較して、既存コードの改変が行えるのが最大の特徴 • AOP的な実装をするのにコード改変が必要なことがある • 例)既存メソッドにトラッキングコードを埋め込む • 例)例外時のリトライ処理を定型的に埋め込む • 逆にいうと、ほかの手段で可能なことはやらない方がいい • 学習コストが高い(類似性のない新言語を1つ覚えるに等しい) • 単純に生産性が非常に低い • 1例としてSource Generator比の3倍のソースコード • 品質の確保も困難 • 1例としてSource Generatorの16倍のテストケース Fody
44.
Copyright 2020 @nuits_jp C#
Metaprogramming Overview まとめ
45.
Copyright 2020 @nuits_jp
Slide 45 IComparableのボイラーコードを生成するライブラリを作ってるので、 完成したらよかったら使ってね! https://github.com/nuitsjp/ComparableGenerator まとめ
46.
Copyright 2020 @nuits_jp
Slide 46 じゃなかった
47.
Copyright 2020 @nuits_jp
Slide 47 .NETのメタプログラミング技術(多分もっとある) 1. CodeDOM 2. Roslyn(ここではNuGet上のライブラリ利用のこと) 3. Reflection 4. Reflection.Emit 5. ExpressionTree 6. T4TextTemplates 7. Source Generator ← New!! 8. Fody / Mono.Cecil メタプログラミング
48.
Copyright 2020 @nuits_jp
Slide 48 • それぞれ適材適所 • いつものとおり、銀の弾丸はない • 向いているものを、向いている場所で使いましょう • 特に!IL弄るのは最終手段 注意点
49.
Copyright 2020 @nuits_jp
Slide 49 ThankYou! おしまい!
Editor's Notes
#2:
それでは始めます。 よろしくお願いします。
#3:
さてC#9.0のリリースとあわせて、Source Generatorがリリースされましたね。 昨今、一部でメタプログラミングが活性化しているように、個人的には感じています。
#4:
そこで今回は
#5:
C#で利用可能な代表的なメタプログラミングについて どういったものが存在し どういうときに、何を使えばいいのか? その大枠を整理してみました。
#6:
1点ご注意いただきたいことがあります。
#7:
今回の発表内容について 抜け漏れ誤りがあるかもしれませんし 多分に主観が含まれています。 お気づきの点がありましたら、ぜひ気軽にかつ「やさしく」ご指摘ください。
#8:
では本題の前に、自己紹介を。
#9:
中村充志と申します。 リコージャパンという会社に所属して 金融系のエンプラ界隈でアーキテクトをやっています。 ブログやTwitterやってますので、フォローしてもらえると喜びます。
#10:
では本題へ。 まず、はじめに メタプログラミングとはなにか?おさらいしましょう。
#11:
Wikipedia様によると
#12:
たとえば、データベース構造からクラスを生成したり クラスを構造解析してJSONへシリアライズしたり つまり、メタデータをもとに、プログラムを生成するプログラミングのことをメタプログラミングと呼びます。
#13:
.NETの代表的なメタプログラミングを集めてみました。 皆さんの推しが入っていなかったらゴメンなさい。 Source Generatorが追加されたのがトピックですね。 今回はこれらのうち
#14:
この辺は除外させていただいて
#15:
この5つについてお話します。
#16:
まずは、どういうときに、何をつかえばいいのか? から、お話しましょう。
#17:
その際、このラインで区切って考えると分かりやすいです。
#18:
上は、基本的に自分自身のためにメタプログラミングする技法で
#19:
それ以外は、自分を含む、誰かのために利用します。 うん、わからん。
#20:
前者について 例えばDapperなどが 実行時に SQLの実行結果をオブジェクトにつめたり、その逆を実現するために 動的に構造解析して、メンバを取得したり設定したりするのに 利用される技術です。
#21:
後者は、前者のように限定されず、使用用途が非常に広いです。 現時点では、定型的実装つまりボイラーコードの自動生成に 利用されているのをよく見かけます。 たとえば、WPF向けにINotifyPropertyChangedの実装を自動的に生成したり DDDするためのバリューオブジェクトの典型的な実装を提供したりです。 実行前に解決されるため、動作が非常に軽快です。 これまで、これ系のメタプログラミングは、ちょっと癖が強かったのですが Source Generatorはその辺りがだいぶ解消されています。 そのため、今後は、Dapperみたいなライブラリが、自分で利用するコードのために Source Generatorを利用するといったケースも増えてくるかもしれません。
#22:
ということで、実際のサンプルを見ていきましょう。
#23:
今回はEqualsのオーバーライドをサポートするライブラリをお題とします。 Identifier属性を宣言されたプロパティで同値比較します。 これをまじめに作ると、結構なボリュームになってしまうので 記載しているような制約を前提とします。 今回、時間の兼ね合いで、コードはざっとだけお見せします。 詳細はGithubに公開しているので、良かったらご覧ください。
#24:
こんな参照じゃなくて、内部のメンバーで比較するコードを いろんな手法で生成します。
#25:
てことで、まずはReflectionからいきましょう! ソリューションを開くと、こんな感じで実装技術ごとにフォルダに分けられて整理されています。 一番上は、Notメタなコードです。 Reflectionは二番目ですね。 開くと、3つプロジェクトがあります。 だいたい、どの実装技術も同じ構成です。 まず実装技術名のプロジェクトがあって、こちらに構文解析される側のコードが入っています。 CustomerとEmployeeがありますね。 ReflectionではこれらでEqualsをオーバーライドして、内部からEqualsクラスのInvokeに 処理を委譲しています。 この実装は、メタプログラミングとついているプロジェクトに含まれています。 中をみると、TypeからIdentifier属性が付いているプロパティインフォを取得しているのが見て取れます。 取得したプロパティインフォを使って、値比較するプロパティの値を取得しています。 PPTXへ
#26:
さてご覧いただいたように、Reflectionは実装が簡単です。 半面、動作速度が遅いです。 そのため、一度だけ実行すればよい自動化ツールの作成なんかで使い勝手が良いです ちなみにどれくらい遅いかというと、今回のコードで
#27:
ざっと1000倍くらい遅いです。 とは言え、単位なナノセコンドなので、使えない遅さという話ではないです。
#28:
ただ、これは改善の余地があって 構造解析のコードをキャッシングすることで性能を改善できます。 実際にコードを見てみましょう。 VSへ Customerコードは同じです。 EqualsのInvokeの実装が異なります。 内部でキャッシュされたInstanceオブジェクトのInvokeInnerメソッドを呼び出しています。 その中では、先ほどのプロパティインフォを取得するコードが含まれていませんね。 こんな感じでキャッシュを使いまわします。 詳細は気になる人は、Githubをご覧ください。 で、実行速度はというと PPTXへ
#29:
だいたい10分の1くらいになりました。
#30:
これは、繰り返し実行すればするほど、差が大きくなります。 Genericな実装でキャッシングを実行する場合、 Static Type Cachingパターンが非常にはまりやすいので ぜひ活用を検討してください。
#31:
続いてExpression Treeです。 実際に動的メタプログラミングではこれが利用されているケースが非常に多いです。 VSへ CustomerコードはReflectionと全く同一です。 実装を見てみるとなんだか少し違いますね。 Expressionというのを組み立てて、最後にCompileしてラムダを生成しています。 このラムダを値の取得に利用します。 さて、この実行速度なのですが PPTXへ
#32:
めっちゃ遅いです! これは実行の都度、Compileが走っているからです。
#33:
ということでReflectionと同じようにキャッシングすると
#34:
劇的に早くすることができます。
#35:
ナノセコンドの世界ですので、ノットメタな世界とおおむね同等といっていいと思います。 Expression Treeは基本的にキャッシングとセットで使いましょう。 こういった特徴があるので、型変換を伴うORMや通信系のライブラリと相性が非常によいです。
#36:
続いてT4テンプレートです。 VSへ T4だけ、メタプログラミングとつくプロジェクトがありません。 これはT4はCustomerのコードと同じプロジェクト内に.ttファイルを配置する必要があるからです。 中身を見てみましょう。 ASP.NETのRazerにもにた、普通のテンプレート構文なファイルですね。 詳細は割愛しますが、このDTEというのが、Visual Studioを表すオブジェクトで そこから含まれるコードのメタ情報を取得します。 この下に、Equalsのコードが生成されます。 これを実行すると PPTXへ
#37:
当たり前ですが、非常に速いです。
#38:
非メタな実装と完全に同等です。 ただ、いろいろ癖がありまして・・・ 本来自動生成するコードは構成管理したくないですよね。 PRにのってきちゃうと、レビューが大変ですし、テストカバレージの扱いにも困ります。 また、コード生成する対象コードが増減しても、自動的に追従してくれないって問題もあります。 VSへ たとえば、Itemクラス、コメントアウトされていなものを外してコンパイルしても・・・ 生成されません。 T4ファイルを保存するか、右クリから実行すると作成されます。 削除するときは右クリ実行しても、こんな中途半端な形で生成されるので 一度全部消してから再生成します。 PPTX 特に最後の問題は、再配布して利用する場合に、利用者がその特徴を理解して使わないといけなかったりするのが困りごとです。 またIDE依存なのでCI/CD時に生成ということができません。 でも、複雑なコード生成も、ものすごく簡単にできちゃうというメリットがあります。
#39:
つぎはいよいよソースジェネレーターです Customerクラスはこれまで同様です。 メタプロ側のプロジェクトの中のSourceGenerator.csでソース生成してます。 見ると分かりますが、べたにStringBuilderにAppend、Appendしてます。 ストリングインターポレーションだとパフォーマンスに問題があるので、そこそこ大きなコード生成はこうする必要があります。 でも、これ面倒ですよね? ってことで、T4テンプレートの出番です。 こいつです。 さっきはプロパティのカスタムツールが、ほにゃららGeneratorになっていましたが 今度はほにゃららProcessorになってます。 こうすると、Append、Appendするコードをテンプレートから生成してくれます。 お前は神か!って感じですよね。 こいつは、配布されないので利用者が意識しなくてよいのでT4のデメリットが薄いです。 さてこいつの本当にすごいのは、デバッグすると ちゃんと生成されたコードもステップ実行できちゃうという点です。やばい。 また実行速度も PTTXへ
#40:
早いですね
#41:
これらの理由からSource Generatorは、利用者に特別な理解を求める必要がなく、 再配布しやすいというのがT4比較時のメリットです。 なので、今後はDapperのようなライブラリでも型変換コードの生成を 動的に実行するのではなく、事前にソース生成しておいて利用する形が流行るかもしれません。 早いですからね。 また、Analyzerとの相性が良いので、ユーザーフレンドリーなライブラリを作りやすいのも特徴です。 VSへ 例えば、Identifier属性は1クラス一つと制限しましたが こうやって二つにすると、ちゃんとエラーを出してあげることができます。 PPTX 利用者からすると、使いやすいですよね。 またIDE非依存なのでCI/CDも簡単です。 良いです。
#42:
最後にFodyです。 これは曲者ですね VSへ こいつは、C#コードではなくて、ビルドされたあとにDLLを直接改変します。 つまりILをいじります。 ここのコメントの下のコードがILの記述ですが、まぁふつう読めないですよね。 でも実行速度は
#43:
早いです。 Source Generatorとかより遅いのは、計測誤差です。
#44:
他と比較した場合、Fodyは既存コードの改変が行えるのが最大の特徴です。 そのため、AOPしたい場合なんかで、Source Generatorなんかじゃ実現できなかったことができちゃうのが強みです。 例えば既存コードにトラッキングコードやリトライ実装を埋め込んだりなんかですね。 ただ逆にいうと、ほかの手段で代替できるものは、他の物を利用したほうが良いです。 まずILを覚えなきゃってことで、類似性のない新言語を1つ覚える必要がありますし 同じ実装するにしても、何倍もコードを書かないといけませんし、必要なテストコードも膨れ上がります。 これは、ソース生成であれば1パターンでいいのが、IL生成だと複数パターン実装しないといけないのがその理由です。 たとえば、メンバの値を取得するにしても、メンバを保持しているのが、クラスなのか、ストラクトなのか、Genericなのか メンバがフィールドなのかプロパティなのか、取得対象がクラスなのかストラクトなのか、それによって全部分岐が入るので 累乗的にやることが増えていきます。 多機能だけど、大変。それがFodyです。
#45:
ということでまとめましょう。
#46:
いま実はIComparableのボイラーコードを生成するSource Generatorのライブラリを作ってます。 できたら、良かったら使ってください!おしまい
#47:
ではなくて
#48:
.NETにはいろんなメタプログラミングの技法があります
#49:
どれもそれぞれに強みがあって適材適所です 向いているものを向いている場所で使いましょう 特にILをいじるのは最終手段ですよ!
#50:
ということで、今度こそおしまいです。 ご清聴ありがとうございました。
Download