从 .NET 10 开始,System.Reflection API InvokeMember、FindMembers 和 DeclaredMembers 使用了更受限的注释,而非使用 DynamicallyAccessedMemberTypes.All。
此更改会影响开发人员实现 IReflect 接口或从 TypeInfo 派生的场景。 先前对DynamicallyAccessedMemberTypes.All的使用过于宽泛,可能会导致意外行为,例如拦截由类实现的接口方法,或生成由于不安全反射调用产生的警告。
引入的版本
.NET 10
以前的行为
以前,受影响的 API 使用了 DynamicallyAccessedMemberTypes.All 注释,该注释过于宽泛。 这可能会导致捕获其他成员,例如类实现的接口方法,并可能导致运行时警告或不安全的反射调用。
新行为
受影响的 API 现在使用更严格的注释,从而更好地控制在反射期间捕获的成员。
破坏性变更的类型
更改原因
引入了此更改以提高 API 中的 System.Reflection 批注的准确性,并解决过度宽松 DynamicallyAccessedMemberTypes.All 批注引起的问题。 这可确保与剪裁和反射方案更好地兼容,减少运行时警告,并防止不安全的反射调用。
建议的措施
如果实现 IReflect 或派生自 TypeInfo,请查看代码并更新批注,使其与新行为保持一致。 具体而言:
请将DynamicallyAccessedMemberTypes.All批注替换为更受限的批注,例如DynamicallyAccessedMemberTypes.PublicMethods、DynamicallyAccessedMemberTypes.NonPublicMethods或其他适当的类型。
以下代码片段演示了一个示例。
class MyType : IReflect { [DynamicallyAccessedMembers( DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties | DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] public object InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target, object?[]? args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParameters) { } }测试反射情境,以确保更新后的注解捕获预期的成员,并且不会引发运行时错误或警告。
有关 DynamicallyAccessedMembers 注释及其用法的详细信息,请参阅 准备 .NET 库进行修整。