You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8 AOT泛型参数无匹配注解引发IL2090错误的解决方法

修复.NET 8 AOT下IL2090反射错误的方案

错误原因

.NET 8 AOT的静态裁剪分析无法确定泛型参数T的哪些成员会被反射访问,因此需要显式告知编译器保留T的公共静态字段,否则这些字段会被AOT裁剪,导致反射调用失败。

方案一:添加动态访问成员注解(推荐)

给泛型参数T添加DynamicallyAccessedMembers注解,指定需要保留的成员类型,让AOT编译器明确要保留T的公共静态字段。

修改后的代码:

using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;

public static class FieldHelper
{
    public static ReadOnlyCollection<T> GetFields<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicStaticFields)] T>()
        where T : class
    {
        return typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static)
            .Where(x => x.IsInitOnly && x.FieldType == typeof(T))
            .Select(x => (T)x.GetValue(null))
            .ToList().AsReadOnly();
    }
}

注解说明

  • DynamicallyAccessedMemberTypes.PublicStaticFields:精准匹配你调用GetFields时传入的BindingFlags.Public | BindingFlags.Static筛选条件,告知编译器保留目标类型的公共静态字段。
  • 使用该注解需要引用System.Diagnostics.CodeAnalysis命名空间。

方案二:关闭单元测试项目的AOT编译

由于该助手方法仅用于单元测试,而单元测试通常不需要AOT编译,可以修改单元测试项目的.csproj文件,关闭AOT编译开关:

<PropertyGroup>
  <AotCompile>false</AotCompile>
</PropertyGroup>

这样单元测试项目会回到JIT模式,反射代码可正常运行,无需修改任何业务代码。

方案三:使用trim.xml保留成员(灵活性差,不推荐)

若不想修改代码,可在项目根目录创建trim.xml文件,为特定测试类型配置保留规则:

<linker>
  <assembly fullname="你的程序集名称">
    <type fullname="你的命名空间.目标测试类型">
      <field name="*" attributes="Public, Static" preserve="all" />
    </type>
  </assembly>
</linker>

然后在.csproj中引用该文件:

<ItemGroup>
  <TrimmerRootDescriptor Include="trim.xml" />
</ItemGroup>

这种方式仅适用于固定的已知类型,因为你的方法是泛型实现,需要为每个测试类型单独配置,灵活性不足。

内容的提问来源于stack exchange,提问作者user246392

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 04:26:23