Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 22, 2025

This PR documents a breaking change introduced in .NET 10.0 where the System.Reflection APIs InvokeMember, FindMembers, and DeclaredMembers now use more restricted annotations instead of the overly permissive DAMT.All.

Overview

The previous use of DAMT.All annotation on these reflection APIs could lead to unintended behavior, such as capturing interface methods implemented by a class or generating warnings due to unsafe reflection calls. This change improves accuracy of annotations and ensures better compatibility with trimming and reflection scenarios.

Impact

This is both a source incompatible and behavioral breaking change that affects developers who:

  • Implement the IReflect interface
  • Derive from System.Reflection.TypeInfo

Developers will need to update their code to use more restricted annotations such as DynamicallyAccessedMemberTypes.PublicMethods, DynamicallyAccessedMemberTypes.NonPublicMethods, or other appropriate types instead of DAMT.All.

Changes in this PR

  • Created /docs/core/compatibility/reflection/10/damt-all-restricted-annotations.md with comprehensive documentation including:
    • Clear explanation of the breaking change
    • Before/after code examples
    • Recommended migration actions
    • List of affected APIs
    • Link to trimming documentation
  • Added entry to the TOC (docs/core/compatibility/toc.yml) under the Reflection section
  • Added entry to the index file (docs/core/compatibility/10.0.md) under Core .NET libraries section

Validation

All changes pass markdownlint validation and follow Microsoft documentation style guidelines.

Fixes #<issue_number>

Original prompt

This section details on the original issue you should resolve

<issue_title>[Breaking change]: Replace DAMT.All with more restricted annotation on InvokeMember/FindMembers/DeclaredMembers</issue_title>
<issue_description>### [Breaking change]: Replace DAMT.All with more restricted annotation on InvokeMember/FindMembers/DeclaredMembers

Description

Starting in .NET 10.0, the System.Reflection APIs InvokeMember, FindMembers, and DeclaredMembers have been updated to use more restricted annotations instead of DAMT.All. This change affects scenarios where developers implement the IReflect interface or derive from System.TypeInfo. The previous use of DAMT.All 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.

This change improves the accuracy of annotations and ensures better compatibility with trimming and reflection scenarios. However, it introduces a breaking change for developers who have implemented IReflect or derived from System.TypeInfo, as they may need to update their annotations to align with the new behavior.

Version

.NET 10.0

Previous behavior

The InvokeMember, FindMembers, and DeclaredMembers APIs used the DAMT.All 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.

For example:

public class MyType : IReflect
{
    public MethodInfo[] GetMethods(BindingFlags bindingAttr)
    {
        // Previous behavior: DAMT.All annotation applied
        // This could capture additional members, including interface methods implemented by the class
    }
}

New behavior

The InvokeMember, FindMembers, and DeclaredMembers APIs now use more restricted annotations, which provide better control over the members captured during reflection. Developers implementing IReflect or deriving from System.TypeInfo must update their annotations to match the new behavior.

For example:

public class MyType : IReflect
{
    [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
    public MethodInfo[] GetMethods(BindingFlags bindingAttr)
    {
        // New behavior: More restricted annotation applied
        // Only public methods are captured, avoiding unintended members
    }
}

Type of breaking change

  • Source incompatible: When recompiled using .NET 10.0 or targeting the new runtime, existing source code may require changes to annotations to compile successfully.
  • Behavioral change: Existing binaries might behave differently at runtime due to the updated annotations.

Reason for change

The change was introduced to improve the accuracy of annotations in System.Reflection APIs and to address issues caused by the overly permissive DAMT.All annotation. This ensures better compatibility with trimming and reflection scenarios, reduces runtime warnings, and prevents unsafe reflection calls.

Recommended action

Developers who implement IReflect or derive from System.TypeInfo should review their code and update annotations to align with the new behavior. Specifically:

  1. Replace DAMT.All annotations with more restricted annotations, such as DynamicallyAccessedMemberTypes.PublicMethods, DynamicallyAccessedMemberTypes.NonPublicMethods, or other appropriate types.
  2. Test reflection scenarios to ensure that the updated annotations capture the intended members and do not introduce runtime errors or warnings.

For example, update code as follows:

Before:

public class MyType : IReflect
{
    public MethodInfo[] GetMethods(BindingFlags bindingAttr)
    {
        // Previous behavior: DAMT.All annotation applied
    }
}

After:

public class MyType : IReflect
{
    [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
    public MethodInfo[] GetMethods(BindingFlags bindingAttr)
    {
        // New behavior: More restricted annotation applied
    }
}

Feature area

  • Core .NET libraries
  • System.Reflection

Affected APIs

  • System.Reflection.IReflect.InvokeMember
  • System.Reflection.IReflect.FindMembers
  • System.Reflection.TypeInfo.DeclaredMembers

Additional resources

For more information on DynamicallyAccessedMembers annotations and their usage, refer to the Microsoft documentation on trimming and reflection.


Finally, please email a link to this breaking change issue to .NET Breaking Change Notifications.</issue_description>

Comments on the Issue (you are @copilot in this section)

Fixes #49414


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: sbomer <787361+sbomer@users.noreply.github.com>
Copilot AI changed the title [WIP] Replace DAMT.All with restricted annotation on reflection APIs Document breaking change: Replace DAMT.All with restricted annotations on reflection APIs Oct 22, 2025
Copilot AI requested a review from sbomer October 22, 2025 18:06
Copilot finished work on behalf of sbomer October 22, 2025 18:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Breaking change]: Replace DAMT.All with more restricted annotation on InvokeMember/FindMembers/DeclaredMembers

2 participants