プログラミング
.NET Framework
第4版
岩永 信之
プログラミング

.NET Framework
第4版

• 原著「CLR via C# Forth Edition」

• CLRの中身
• .NETプログラムの内部動作の仕組み
プログラミング

.NET Framework
・・・
C#
コンパイラ

.NET Framework
標準クラス
ライブラリ

VB
コンパイラ

その他の
コンパイラ

中間言語(IL)コード
仮想実行環境
CLR
ネイティブ コード

この辺りが
主役の本
普段、あまり意識しない
直接触れない基礎
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
Reflection
Type型とTypeInfo型
Reflection APIの変更
• Type型からTypeInfo型を分離

• .NET 4.5では後方互換性のために“追加”
• .NET Core(ストア アプリ向け)では破壊的変更
• ポータブルな実装したければ、新APIの利用が必要

どうしてこうなったかというと…
• 名前空間整理
(SystemとSystem.Reflection)
• 2種類の型情報
(TypeDefとTypeRef)
型情報の使いどころ
Type型(System)
の基本情報

型の判定
is演算子

as演算子

x.GetType() == typeof(T)

メンバー情報の取得
DeclaredMembers
BaseType
ImplementedInterfaces

リフレクション情報
(System.Reflection)
動的実行
Reflection.Emit
DynamicInvoke
Experssion.Compile
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
定義側アセンブリ
不要

System.Reflection
名前空間への依存低減

• TypeInfo型(System.Reflection名前空間)
=TypeDef
• TypeInfo型からFieldInfoなどを取る
Reflectionまとめ
• Type型からTypeInfo型を分離
• System.Reflection名前空間への依存低減
• TypeRef情報だけを取れるように
• 静的解析ツールなどで有用

• .NET 4以前 → .NET Core移行では注意が必要
• 破壊的変更になっている
• (.NET 4.5の場合は単なる追加)
WinRT
言語プロジェクション
WinRT (Windows Runtime)
• 関連する技術/スタイルはいろいろあるものの
Windows APIを一新

XAML

Windows ストア アプリ

Immersive UI

MS Design Style

C++ ⇔ .NET ⇔ JavaScript相互運用
.NET Core (ストア アプリ向け.NETライブラリ)
C++/CX

WinMD

言語プロジェクション
WinRT (Windows Runtime)
• CLR (本書)的に関係するのは
Windows APIを一新

XAML

Windows ストア アプリ

Immersive UI

MS Design Style

C++ ⇔ .NET ⇔ JavaScript相互運用
この部分
.NET Core (ストア アプリ向け.NETライブラリ)
C++/CX

WinMD

言語プロジェクション
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の型
IList<T>
IReadOnlyList<T>

WinRTの型
IVector<T>
IVectorView<T>

IEnumerable<T>
IDictionary<T>

IIteratable<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内で
定義されたメソッドで明示的に型変換
OpenStreamForReadAsync
AsInputStream
Stream
AsStream
AsTask
Task
AsAsyncAction
AsAsyncOperation

IStorageFile
IStream

IAsyncAction
IAsyncOperation

要は単なるライブラリ。本書的には関連薄い部分
WinRTまとめ
• WinRT、CLR的に関係あるのは
• WinMD、CLRプロジェクション

• WinMD
• 要はRCW自動生成

• CLRプロジェクション
• CLRが内部的に一部の型を置き替え
async/await
Jeffrey 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:

IEnumerable<int> Method()
{
yield return 1;

Current = 1;
_state = 1;
return true;
case 1:
Current = 2;
_state = 2;
return true;
case 2:

yield return 2;

}
}

}

}

default:
return false;
イテレーター
• 中断と再開

class MethodEnumerator : IEnumerator<int>
{
public int Current { get; private set; }
private int _state = 0;
public bool MoveNext()
{
switch (_state)
{
case 0:

状態の記録

Current = 1;
Current = 1;
_state = 1;
_state = 1;
return true;
中断
return 1:
case true;
case 1: = 2;
Current
_state = 2;
return true; 再開用のラベル

IEnumerable<int> Method()
{
yield return 1;

yield return 2;

case 2:
}
}

}

}

default:
return false;
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
など

• 訳本
• 翻訳のクオリティかなり上がったと思います!

プログラミング .NET Framework 第4版