Native AOT 不支持反射动态类型操作、LINQ表达式树运行时编译、托管堆代码生成及隐式泛型实例化,因所有类型和方法绑定必须在编译期固化。

Native AOT 不支持反射的动态类型操作
Native AOT 在编译期必须确定所有类型和成员的布局,无法在运行时通过 Assembly.Load、Type.GetType 或 Activator.CreateInstance(string) 动态加载或实例化未知类型。即使类型存在,只要路径是字符串形式(如 "MyApp.Foo"),AOT 就会报错或静默失败。
常见错误现象:System.TypeLoadException: Could not load type 或链接阶段直接失败(如 ILLink 报 Unresolved assembly)。
- 允许:使用已知类型的强引用,如
typeof(Foo)、new Foo() - 禁止:基于字符串的类型解析、
Assembly.GetExecutingAssembly().GetTypes()(除非显式保留) - 折中方案:用
[DynamicDependency]或rd.xml声明需保留的类型,但仅限编译期可枚举的集合
Native AOT 不支持 LINQ to Objects 的完整表达式树执行
AOT 无法在运行时编译 Expression 为委托(即不支持 expr.Compile())。所有表达式必须能在编译期被 ILLink 静态分析并内联,否则链接器会剪掉相关代码,导致 NotSupportedException。
使用场景:Entity Framework Core 的客户端求值、自定义查询构建器、运行时拼接条件表达式。
- 允许:
list.Where(x => x.Id > 5)(编译为普通委托,非表达式树) - 禁止:
Expression> expr = x => x.Age > 18; var func = expr.Compile(); - 替代方式:改用预定义委托、策略模式或代码生成(如 Source Generator 输出静态方法)
Native AOT 不支持托管堆上的运行时代码生成
包括 Reflection.Emit(AssemblyBuilder、TypeBuilder)、Delegate.CreateDelegate(部分重载)、以及依赖 JIT 的任何机制。AOT 输出的是纯原生机器码,没有运行时编译器。
典型踩坑点:某些序列化库(如旧版 Newtonsoft.Json 的默认设置)、RPC 框架的代理生成、或手写 IL 织入逻辑。
- 允许:
Delegate.CreateDelegate(typeof(Func(目标方法必须已存在且可达)), obj, "MethodName") - 禁止:
DynamicMethod、ILGenerator、RuntimeMethodHandle.GetFunctionPointer() - 兼容做法:用
System.Text.Json(AOT 友好)、或启用JsonSerializerOptions.PreferredObjectCreationHandling = ObjectCreationHandling.Reuse避免反射构造
Native AOT 对泛型实例化的限制比 JIT 更严格
AOT 要求每个泛型闭包(如 List、Dictionary)在编译期明确出现过,否则不会为其生成本地代码。隐式泛型实例(如仅通过反射触发)会被剪掉。
性能影响:过度保守的泛型使用会导致二进制体积膨胀;过于激进的剪裁则引发运行时 MissingMethodException。
- 必须显式触发:在代码中写
new List或标记() [RequiresUnreferencedCode]提示工具链保留 - 接口实现泛型类时,若实现类未被直接引用,需用
[DynamicDependency]关联 -
typeof(T).IsGenericType等反射检查仍可用,但不能据此决定是否实例化新泛型类型










