|
| 1 | +--- |
| 2 | +title: "Breaking change: More restricted annotations on InvokeMember/FindMembers/DeclaredMembers" |
| 3 | +description: "Learn about the breaking change in .NET 10 where System.Reflection APIs InvokeMember, FindMembers, and DeclaredMembers use more restricted annotations instead of DynamicallyAccessedMemberTypes.All." |
| 4 | +ms.date: 10/09/2025 |
| 5 | +ai-usage: ai-generated |
| 6 | +--- |
| 7 | + |
| 8 | +# More restricted annotations on InvokeMember/FindMembers/DeclaredMembers |
| 9 | + |
| 10 | +Starting in .NET 10, the <xref:System.Reflection> APIs <xref:System.Reflection.IReflect.InvokeMember%2A>, <xref:System.Type.FindMembers%2A>, and <xref:System.Reflection.TypeInfo.DeclaredMembers> use more restricted annotations instead of <xref:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All?displayProperty=nameWithType>. |
| 11 | + |
| 12 | +This change affects scenarios where developers implement the <xref:System.Reflection.IReflect> interface or derive from <xref:System.Reflection.TypeInfo>. The previous use of <xref:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All?displayProperty=nameWithType> was overly permissive and could lead to unintended behavior, such as capturing interface methods implemented by a class or generating warnings due to unsafe reflection calls. |
| 13 | + |
| 14 | +## Version introduced |
| 15 | + |
| 16 | +.NET 10 |
| 17 | + |
| 18 | +## Previous behavior |
| 19 | + |
| 20 | +Previously, the [affected APIs](#affected-apis) used the <xref:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All?displayProperty=nameWithType> annotation, which was overly permissive. This could result in capturing additional members, such as interface methods implemented by a class, and potentially cause runtime warnings or unsafe reflection calls. |
| 21 | + |
| 22 | +## New behavior |
| 23 | + |
| 24 | +The [affected APIs](#affected-apis) now use more restricted annotations, which provide better control over the members captured during reflection. |
| 25 | + |
| 26 | +## Type of breaking change |
| 27 | + |
| 28 | +This change is a [behavioral change](../../categories.md#behavioral-change) and can affect [source compatibility](../../categories.md#source-compatibility). |
| 29 | + |
| 30 | +## Reason for change |
| 31 | + |
| 32 | +The change was introduced to improve the accuracy of annotations in <xref:System.Reflection> APIs and to address issues caused by the overly permissive <xref:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All?displayProperty=nameWithType> annotation. This ensures better compatibility with trimming and reflection scenarios, reduces run-time warnings, and prevents unsafe reflection calls. |
| 33 | + |
| 34 | +## Recommended action |
| 35 | + |
| 36 | +If you implement <xref:System.Reflection.IReflect> or derive from <xref:System.Reflection.TypeInfo>, review your code and update annotations to align with the new behavior. Specifically: |
| 37 | + |
| 38 | +1. Replace <xref:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All?displayProperty=nameWithType> annotations with more restricted annotations, such as <xref:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods?displayProperty=nameWithType>, <xref:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods?displayProperty=nameWithType>, or other appropriate types. |
| 39 | + |
| 40 | + The following code snippet shows an example. |
| 41 | + |
| 42 | + ```csharp |
| 43 | + class MyType : IReflect |
| 44 | + { |
| 45 | + [DynamicallyAccessedMembers( |
| 46 | + DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | |
| 47 | + DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | |
| 48 | + DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties | |
| 49 | + DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] |
| 50 | + public object InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target, |
| 51 | + object?[]? args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParameters) |
| 52 | + { } |
| 53 | + } |
| 54 | + ``` |
| 55 | + |
| 56 | +1. Test reflection scenarios to ensure that the updated annotations capture the intended members and don't introduce run-time errors or warnings. |
| 57 | + |
| 58 | +For more information on `DynamicallyAccessedMembers` annotations and their usage, see [Prepare .NET libraries for trimming](../../../deploying/trimming/prepare-libraries-for-trimming.md). |
| 59 | + |
| 60 | +## Affected APIs |
| 61 | + |
| 62 | +- <xref:System.Reflection.IReflect.InvokeMember(System.String,System.Reflection.BindingFlags,System.Reflection.Binder,System.Object,System.Object[],System.Reflection.ParameterModifier[],System.Globalization.CultureInfo,System.String[])?displayProperty=fullName> |
| 63 | +- <xref:System.Type.FindMembers(System.Reflection.MemberTypes,System.Reflection.BindingFlags,System.Reflection.MemberFilter,System.Object)?displayProperty=fullName> |
| 64 | +- <xref:System.Reflection.TypeInfo.DeclaredMembers?displayProperty=fullName> |
0 commit comments