-
Couldn't load subscription status.
- Fork 5.2k
Description
The implementation of System.Reflection.Metadata PropertyDefinition and EventDefinition swallows some accessors and doesn't make them available publically. This has been marked as TODO in the source code. These 'other' accessors are not often encountered, but handling them is required for certain special case tooling.
usage of 'other' property accessors
- The .NET Framework exposes 'other' accessors through PropertyInfo.GetAccessors
- .NET assemblies generated by the 'tlbimp' tool can generate this metadata when a COM property has both a PUT and a PUTREF accessor.
- They are valid metadata, even though rarely used, but if you build tools for processing or inspecting .NET assemblies (like tlbexp or ildasm do) you want to handle them.
The last point is a real-world use case I have. The tlbexp functionality built into the .NET Framework requires loading an assembly into the AppDomain to generate a TLB. Loading the assembly can fail for various reasons, so generating a TLB by only inspecting metadata is desireable. The omission of 'other' accessors is a problem here.
Proposed API
namespace System.Reflection.Metadata
{
public struct PropertyAccessors
{
// Existing
public MethodDefinitionHandle Getter { get; }
public MethodDefinitionHandle Setter { get; }
// New
public ImmutableArray<MethodDefinitionHandle> Others { get; }
}
public struct EventAccessors
{
// Existing
public MethodDefinitionHandle Adder { get; }
public MethodDefinitionHandle Remover { get; }
public MethodDefinitionHandle Raiser { get; }
// New
public ImmutableArray<MethodDefinitionHandle> Others { get; }
}
}Details
In the large majority of cases there will be no 'other' accessors in the metadata. It is trivially possible to implement this case without any additional allocations compared to the current implementation.
For the purpose of the discussion I have provided an initial implementation of the suggested change.
Updates
- Expose other accessors directly on the
PropertyAccessorsandEventAccessorsstructs instead of returning them as an out-param