Skip to content

Portable mechanism needed to determine if two MemberInfos are backed by the same metadata definition #16288

@nguerrera

Description

@nguerrera

Currently, there is a hole in reflection whereby there's no straight-forward way to determine if:

1. MemberInfos differ only by ReflectedType (i.e. they are the same member, but one of them was obtained from a derived type.)

public class C { public int F; }
public class D : C {}

static class Program {
    static void Main(string[] args) {
        var f1 = typeof(C).GetField("F");
        var f2 = typeof(D).GetField("F");
        System.Console.WriteLine(f1.Equals(f2)); // False
    }
}

2. One MemberInfo is a generic instantiation of another.

static class Program {
    static void Main(string[] args) {
        var m1 = typeof(List<>).GetMethod("Add");
        var m2 = typeof(List<int>).GetMethod("Add");

        // how to determine that m2 is instantiated from m1?
    }
}

On platforms that support the MetadataToken, this can be worked around by comparing the tokens, but without them, one has to resort to error-prone comparisons of the declaring type, name, and signature.

There should be a first-class portable way to address both.

Proposal for New API: HasSameMetadataDefinitionAs

Add a new API that determines if a member is backed/instantiated from the same metadata definition. In ECMA-335 terms, this is a member/type from the same module that has the same metadata def token. Platforms like .NET Native that do not keep around metadata tokens should still preserve enough information to answer this query portably.

public class MemberInfo {
    public virtual bool HasSameMetadataDefinitionAs(MemberInfo other);
    ...
}

A mostly correct implementation is:

return Module.Equals(other.Module) && MetadataToken ==  other.MetadataToken;

But that ignores edge cases such as TypeInfo instances for array, byref, pointer, and type parameters types, which we'd need to spec and test.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions