-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
The queryable LINQ operators are currently marked with [RequiresDynamicCode] (e.g. Where), because their implementation uses MakeGenericType. This makes them incompatible with NativeAOT.
In typical LINQ providers, the expression tree doesn't end up getting compiled and executed, but rather translated to something else (e.g. SQL); this means that the Types and MethodInfos in the tree are only there for the proper tree structure, and we don't need them to actually contain code. However, MakeGenericType and MakeGenericMethod are currently eager, and throw right away in NativeAOT if the native code isn't pregenerated.
To solve this, we'd need to be able to make lazy Types, MethodInfos, which only throw if a method/property is actually invoked on them. From a conversation with @jkotas, the eager behavior of the reflection types was done in order to provide fail-fast behavior to users; we could revisit this decision.
As an alternative, since Type/MethodInfo/PropertyInfo are abstract base classes, we could add lazy implementations of these. These implementations could either throw if code is invoked, or lazily call the real MakeGenericMethod when needed (which would fail in NativeAOT). Construction of these lazy types should be exposed as a new API, since LINQ providers such as EF would need to make use of them as well (otherwise LINQ providers would need to duplicate the lazy types internally).
Thanks for @jkotas for the suggestions and conversation.