如何解决PropertyInfo.PropertyType未标注DynamicallyAccessedMembersAttribute的裁剪兼容问题?
解决.NET裁剪场景下反射访问属性类型成员的标注问题
你遇到的问题是因为仅标注了输入Type需要保留公共属性,但裁剪分析器不知道你还需要访问这些属性的类型的特定成员(这里是静态Parse方法)。可以通过精准标注属性类型的成员需求来解决,以下是具体方案:
方案一:直接标注PropertyType变量
在获取PropertyType后,用[DynamicallyAccessedMembers]标记该变量,明确告知裁剪工具需要保留该类型的哪些成员。修改后的代码如下:
using System.Diagnostics.CodeAnalysis; using System.Reflection; class Example { public static void Test([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type type) { var prop = type.GetProperty("Bar")!; // 明确标注该类型需要保留公共静态方法(对应Parse方法的需求) [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicStaticMethods)] Type propType = prop.PropertyType; var parseMethod = propType.GetMethod( "Parse", BindingFlags.Public | BindingFlags.Static, new[] { typeof(ReadOnlySpan<char>), typeof(IFormatProvider) }); Console.WriteLine(parseMethod); } } class Foo { public int Bar { get; set; } }
- 可根据实际需求调整
DynamicallyAccessedMemberTypes枚举值:比如需要访问实例方法就用PublicMethods,需要字段就用PublicFields等,精准控制裁剪范围。
方案二:使用RequiresDynamicCodeAttribute(适合复杂反射场景)
如果反射逻辑复杂,无法精准枚举需要保留的成员类型,可以给整个方法标注[RequiresDynamicCode],告知裁剪工具该方法依赖动态代码,不要裁剪相关类型的成员:
using System.Diagnostics.CodeAnalysis; using System.Reflection; class Example { [RequiresDynamicCode("该方法通过反射访问属性类型的静态Parse方法,需要保留相关动态代码支持")] public static void Test([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type type) { var prop = type.GetProperty("Bar")!; var parseMethod = prop.PropertyType.GetMethod( "Parse", BindingFlags.Public | BindingFlags.Static, new[] { typeof(ReadOnlySpan<char>), typeof(IFormatProvider) }); Console.WriteLine(parseMethod); } } class Foo { public int Bar { get; set; } }
- 这种方式会放宽裁剪限制,适合无法精准标注的场景,但可能导致最终程序体积更大。
原理说明
裁剪分析器通过DynamicallyAccessedMembersAttribute追踪反射依赖:
- 最初仅标注输入
Type需要保留公共属性,分析器只确保type的公共属性不被裁剪。 - 访问
prop.PropertyType并调用其GetMethod时,分析器无法确定该类型需要保留哪些成员,因此抛出警告。 - 标注
propType变量的成员需求后,分析器明确知道要保留该类型的指定成员,从而消除警告并避免裁剪错误。
内容的提问来源于stack exchange,提问作者Sven
相关产品推荐
相关产品推荐

