私が理解していることを確認するために、誰かがラムダ式がリフレクションを使用していることを確認できますか?
3 に答える
できますが、必須ではありません。それらがデリゲートにコンパイルされている場合、リフレクションは必要ありません。ただし、それらがab式ツリーにコンパイルされている場合、式ツリーは完全にリフレクションベースです。式ツリーの一部は、メタデータトークン(ldtoken)から直接アセンブルできます(特定のメソッド(演算子、ゲッター/セッター、タイプなど))が、他の一部はアセンブルできません。これにはプロパティが含まれます(PropertyInfo
トークンでロードすることはできません)-したがって、コンパイルされたラムダのILには明示的にGetProperty
etcを含めることができます。
ただし、どのようにロードされても(トークンまたはリフレクション)、式ツリーはMemberInfo
リフレクション(など)で表現されます。これは後でコンパイルされるか、プロバイダーによって分析される可能性があります。
パフォーマンスを向上させるために、式コンパイラは式ツリーの一部またはすべてをキャッシュし、それを再利用する場合があります。
ラムダ式は、コンパイラによって無名関数または式ツリーに変換されます。リフレクションは実行時にのみ実行できるため、どちらの場合でもコンパイラーがリフレクションをどのように処理するかを考えると、リフレクションはまったくわかりません。
実行時に、ラムダ式により、非常に特殊な状況でリフレクションが使用される場合があります。
匿名関数の場合:何かを明示的に反映する匿名関数を作成すると、ラムダは呼び出されたときにその反映を実行します。もちろん、これは「適切な」方法で反省している場合と同じです。
式ツリー(つまりExpression<TDelegate>
、一部のタイプの値TDelegate
)の場合:実行時にを使用するときにそれらを使用すると、クエリプロバイダーIQueryable
によってリフレクションが使用される可能性があります。たとえば、次のことを行うと仮定します。
var user = new User { Id = 42 };
var posts = Queryable.Posts.Where(p => p.UserId == user.Id);
posts
が実現されようとしているとき、クエリプロバイダーは、変数のUserId
と等しい投稿を検索する必要があることを確認します。そのIDは実行時に特定の既知の値を持っているため、クエリプロバイダーはそれをからフィッシュする必要があります。それを行うことを決定する1つの方法は、反省によるものです。Id
user
user
ラムダ式は、デリゲートを作成するための単なるコンパイラー構文シュガーです。ここでは反射は使用されていません。