EqualityComparer<T>.Defaultの実装を追ってみる。

気になりません?

純粋にどうやって生成してるのか疑問に思ったので気が済むまで追ってみる。
完全に備忘録でありいろいろ雑。

16行目が生成しているところ。関数はこんな感じ。

いろいろ知らない。
Typeはこう。

でRuntimeTypeはこう。internalらしい。

でこのTypeInfoが

なるほどRuntimeTypeはランタイムの中だけで使われる具象っぽい。

一番始めにbyte型か確認してる。これはいい。
次に

これはなにか。

でIEquatableという型を作ってIsAssignableFromでtype型がMakeGenericTypeで生成された型(これはインターフェース)が実装されているか、を調べている。
typeがintの場合、Int32の型の定義はこんな感じであり、

IEquatableが実装されているためtrueが帰ってくる形になる。
リフレクション自分じゃそんなに使わないのでよく知らないのですが、いろいろできるんですねぇ。Typeから生えてるメソッドの充実ぶりに驚いている。
そのあとはジェネリック型かみて、それがNullable型かどうか、Enum型かどうかを見てますね。
実際にobjを作っているのは

の4つであることがわかる。byteとNullableは特別扱いなんですねー。
最終的にobjがnullだった場合、typeof (ObjectEqualityComparer<object>)が渡されるのは分かる(Object.Equalsとかが使われるからだろう)のだが、インターフェースが実装されていた場合、typeof (GenericEqualityComparer<int>)が渡されているのは一体どういうことだろう。なぜint。みてみると

\\internal static extern//

C#で書かれておらず、C++で実装されているらしいですねこのやろう…。
しかし.NET Coreはオープンソースです。ならばソースを見てやろうじゃないかとなるわけです。clrにかかれていると思われるので、ここでCreateInstanceForAnotherGenericParameterで検索します。
するとこれに引っかかります。
引用すると

まぁおそらく第一引数の文字列が呼び出し名で、第二引数が呼び出される実際のものなのだろう。ということで次はCreateInstanceForGenericTypeをリポジトリ内で検索する。そうするとこれに引っかかる。引用しつつコメント書きながら読んでみます。

わからんw

関数テーブルからAllocateしていたりInstantiateしてるんですね。よくわからないけど面白い。これ以上に深追いは時間が無限に溶ける気がするので止めておく。。。

結論

早々にCLRのC++の関数呼び出しにぶつかってしまい、消化不良…。もんもん。

neno

都内のJK大学生。趣味はドールと一緒にお出かけして撮影すること。C++とC#が好き。C++は主にリアルタイム画像処理, C#はUnity, WPF, UWP, .NET Coreとかいろいろ。ASPとXamarin学習中。 専攻はCV。最近のおもちゃはHoloLens。

あわせて読みたい

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

%d人のブロガーが「いいね」をつけました。