-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
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.