Upload
-
View
3.868
Download
1
Embed Size (px)
DESCRIPTION
2013/10/26(土) 「プログラミング .NET Framework 第4版 」座談会 http://atnd.org/event/E0019986 にて発表。
Citation preview
プログラミング.NET Framework第 4 版
++C++; // 未確認飛行 C
岩永 信之
プログラミング
.NET Framework 第 4 版• 原著「 CLR via C# Forth Edition 」• CLR の中身• .NET プログラムの内部動作の仕組み
プログラミング
.NET Framework
C#コンパイ
ラ
VBコンパイ
ラ
その他のコンパイ
ラ
・・・
中間言語( IL )コード
仮想実行環境CLR
ネイティブ コード
.NET Framework
標準クラスライブラリ
この辺りが主役の本
普段、あまり意識しない直接触れない基礎
Jeffrey Richiter (原著作者)
• 「 Windows Via C/C++ 」「 Advanced Windows 」なども執筆• Windows のスレッド周りとかかなり詳しい
• Windows/.NET 系のコンサル• CLR の設計にもかかわる• C# 5.0 の async/await のアイディアの原型も
.NET を学ぶ
• .NET の基礎を押さえたい人• ステップアップしたい人• 基礎知識はデバッグや障害対応で役立つ• 性能面や安全面でもよりよいコードを
• Java や Ruby など、他の環境をガッツリやっていた人が .NET を使うことになった時などにも
.NET に学ぶ
• .NET には、アプリ開発に必要ないろいろ詰まってる• .NET (というか仮想実行環境 / フレームワーク)
を使わずに自前実装が必要なことにぶつかったとしても、かなり役立つ知識
• そういう、 .NET の中身の詳細が本書に
例えば本書には
• CLR の実行モデル• メタデータの構造、型システムの詳細• コア機能• 例外、 GC 、 AppDomain
• CLR をネイティブ アプリでホストするには• 非同期処理
「第 4 版」
• 要は、 .NET 4 → .NET 4.5 対応• .NET 4.5 対応のうち、
本書 ( というか CLR) 的に関連深いのは :• TypeInfo 型と Type 型• WinRT• async/await
訳本に関して
翻訳のレベルかなり上がった自信があります!
書籍紹介まとめと、残り
• .NET からいろいろ学んでください• 本書は .NET の内部に非常に詳しい
• 座談会、お楽しみに!
• このセッションの残りは :• 「第 4 版」での追加部分• というか、 .NET 4 → .NET 4.5 追加部分• TypeInfo 、 WinRT 、 async/await
ReflectionType 型と TypeInfo 型
Reflection API の変更
• Type 型から TypeInfo 型を分離• .NET 4.5 では後方互換性のために“追加”• .NET Core (ストア アプリ向け)では破壊的変更• ポータブルな実装したければ、新 API の利用が必
要
どうしてこうなったかというと…• 名前空間整理
(System とSystem.Reflection)
• 2 種類の型情報(TypeDef と TypeRef)
型情報の使いどころ
動的実行
型の判定is 演算子 as 演算子
x.GetType() == typeof(T)
Reflection.Emit
DynamicInvoke
Experssion.Compile
メンバー情報の取得DeclaredMembersBaseType
ImplementedInterfaces
Type 型( System )の基
本情報
リフレクション情報(System.Reflection)
2 種類の型情報
• IL 的に、型情報テーブルは 2 種類( 2 段階)あるTypeDef TypeRef
型の具体的な定義 型を参照するための情報型を定義したアセンブリがないと取り出せない情報
型を定義したアセンブリがなくても知れる情報
• 名前、名前空間• メンバー情報• 継承階層の情報
• どこで定義されているか
• 名前、名前空間
少ない情報緩い制約
2 種類の型情報
• IL 的に、型情報テーブルは 2 種類( 2 段階)あるTypeDef TypeRef
型の具体的な定義 型を参照するための情報型を定義したアセンブリがないと取り出せない情報
型を定義したアセンブリがなくても知れる情報
• 名前、名前空間• メンバー情報• 継承階層の情報
• どこで定義されているか
• 名前、名前空間
• プログラムを実行するためには TypeDef が必要
• アセンブリが欠けていると実行不能
2 種類の型情報
• IL 的に、型情報テーブルは 2 種類( 2 段階)あるTypeDef TypeRef
型の具体的な定義 型を参照するための情報型を定義したアセンブリがないと取り出せない情報
型を定義したアセンブリがなくても知れる情報
• 名前、名前空間• メンバー情報• 継承階層の情報
• どこで定義されているか
• 名前、名前空間
参照先のアセンブリが欠けていても、どこの何を参照しているか名前くらいはわかる
.NET 4 以前の Type 型
全部 Type 型でやってた• Type 型を得るためには TypeDef 必須• 定義側アセンブリ必須
• 参照側アセンブリ単体で読めない• 静的解析ツールとかで困ることがある
• Type 型から FieldInfo などを取る• System 名前空間が System.Reflection 名前空
間に結構大きく依存
.NET 4.5 以降の Type 型
Type 型と TypeInfo 型に分離• Type 型 (System 名前空間 )= TypeRef
• TypeInfo 型 (System.Reflection 名前空間 )= TypeDef• TypeInfo 型から FieldInfo などを取る
定義側アセンブリ不要
System.Reflection 名前空間への依存低減
Reflection まとめ
• Type 型から TypeInfo 型を分離• System.Reflection 名前空間への依存低減• TypeRef 情報だけを取れるように
• 静的解析ツールなどで有用
• .NET 4 以前 → .NET Core移行では注意が必要• 破壊的変更になっている• ( .NET 4.5 の場合は単なる追加)
WinRT言語プロジェクション
WinRT (Windows Runtime)
• 関連する技術 / スタイルはいろいろあるものの
.NET Core ( ストア アプリ向け .NET ライブラリ )
C++ ⇔ .NET ⇔ JavaScript相互運用
Windows API を一新 Windows ストア アプリ
C++/CX WinMD 言語プロジェクション
XAML Immersive UI MS Design Style
WinRT (Windows Runtime)
• CLR ( 本書 ) 的に関係するのは
.NET Core ( ストア アプリ向け .NET ライブラリ )
C++ ⇔ .NET ⇔ JavaScript相互運用
Windows API を一新 Windows ストア アプリ
C++/CX WinMD 言語プロジェクション
XAML Immersive UI MS Design Style
この部分
CLR から見た WinRT
• WinMD• C++/CX をコンパイルすると自動で作られる
メタデータ• ほぼ、 RCW ※
• .NET のメタデータとフォーマット同じ• データ形式的に、ほんと RCW
• つまるところ• C++ から見て : TypeLibary 書くより楽• .NET から見て : 昔の COM より参照が楽
※ Runtime Callable Wrapper: .NET から COM を呼ぶためのラッパー
+ 言語プロジェクション
言語プロジェクション
•一部の型は別の型に置き替える• C++ から見ると IVector<T>
.NET から見ると IList<T>みたいな• ネイティブ /.NET/JavaScript で、それぞれの流儀
でプログラムを書けるように
2 種類のプロジェクション
• CLR プロジェクション• CLR が内部的に勝手に置き替える• IVector<T> ⇔ IList<T> とか
• フレームワーク プロジェクション• 変換ライブラリが標準提供されているだけ• そのライブラリの呼び出しは手動で• AsTask拡張メソッドとか
CLR プロジェクションの例
.NET の型 WinRT の型IList<T> IVector<T>
IReadOnlyList<T> IVectorView<T>
IEnumerable<T> IIteratable<T>
IDictionary<T> IMap<T>
この他、 Uri 型とか TimeSpan 型は、.NET 側 : System 名前空間WinRT 側 : Windows.Foundation 名前空間に相互変換される
仕組み : IL Token タイプ
• Token: 型 / メンバーを識別するための 4byte整数• そのうち 1byte は、 TypeDef/TypeRef のどちら
のテーブルを探せばいいか、タイプ判定に使う• (残り 3byte はテーブル内のインデックス)
• .NET 4.5 で、これに、 CLR プロジェクション用のタイプが増えたみたい
フレームワーク プロジェクション• System.Runtime.WindowsRuntime.dll
内で定義されたメソッドで明示的に型変換
StreamIStorageFileIStream
OpenStreamForReadAsyncAsInputStream
AsStream
TaskIAsyncActionIAsyncOperation
AsTask
AsAsyncActionAsAsyncOperation
要は単なるライブラリ。本書的には関連薄い部分
WinRT まとめ
• WinRT 、 CLR 的に関係あるのは• WinMD 、 CLR プロジェクション
• WinMD• 要は RCW 自動生成
• CLR プロジェクション• CLR が内部的に一部の型を置き替え
async/awaitJeffrey Richiter といえば非同期
Jeffrey Richter
• 原著作者、スレッド / 非同期が大好き• Advanced Windows 時代から• 的な「非同期ロック待ち」がらみの特許取ってる
(マイクロソフトに売却済み)• SemaphoreSlim.WaitAsync がこのアイディアに似た
実装• C# 5.0 の async/await の設計にも少し関わって
るっぽい
AsyncEnumerator
• 第 3 版までは作者のオレオレ async ライブラリの解説が入ってた• yield return ベースで現在の async/await 的なも
のを実現• 第 4 版では async/await の説明に置き替え
async/await の内部実装
• イテレーター (yield) に似たコード生成• Awaitable/Awaiter パターン
イテレーター
• 中断と再開class MethodEnumerator : IEnumerator<int>{ public int Current { get; private set; } private int _state = 0; public bool MoveNext() { switch (_state) { case 0: Current = 1; _state = 1; return true; case 1: Current = 2; _state = 2; return true; case 2: default: return false; } }}
IEnumerable<int> Method(){ yield return 1;
yield return 2;
}
イテレーター
• 中断と再開class MethodEnumerator : IEnumerator<int>{ public int Current { get; private set; } private int _state = 0; public bool MoveNext() { switch (_state) { case 0: Current = 1; _state = 1; return true; case 1: Current = 2; _state = 2; return true; case 2: default: return false; } }}
IEnumerable<int> Method(){ yield return 1;
yield return 2;
}
Current = 1;_state = 1;return true;case 1:
状態の記録
中断
再開用のラベル
await の展開結果(コンセプト)• コンセプト的には イテレーター +
ContinueWith
async Task<int> Method(){ var x = await task1; var y = await task2;}
_state = 1;if (!task1.IsCompleted){ task1.ContinueWith(a); return;}case 1:var x = task1.Result;
中断
状態の記録
結果の受け取り
再開用のラベル
await の展開結果
• 実際はもう少し複雑• Awaiter というものを介していたり( Awaitable
パターン)_state = 1;var awaiter1 = task1.GetAwaiter();if (!awaiter1.IsCompleted){ awaiter1.OnCompleted(a); return;}case 1:var x = awaiter1.GetResult();
• こいつが同期コンテキストを拾い上げていたりする• Awaiter を自作することで、
await の挙動を変更可能• Task 以外も await可能
async/await まとめ
• C# 5.0 の async/await• イテレーター (yield) に似たコード生成• Awaitable/Awaiter
• Jeffey Richiter といえばスレッド / 非同期• async/await に近いコンセプトのライブラリ作っ
て公開してた (AsyncEnumerator)
まとめ
• プログラミング .NET Framework 第 4 版• .NET の内側
• より深い知識でステップアップを• 第 4 版 (.NET 4 → .NET 4.5) では
• TypeInfo 型• WinRT• async/await
など• 訳本
• 翻訳のクオリティかなり上がったと思います!