I'm seeing two different behaviors based on the CLR that my application is being run under. In one case it returns an abstract property on a closed type and in another it does not. As the property is abstract, it feels more like the first is correct.
I have tested by compiling the following under VS2010 targeting .NET-3.5 SP1 and then copying the physical executable to another machine with a different CLR minor revision:
public abstract class BaseEntity<TId>
{
public abstract TId PK { get; set; }
}
public class DerivedEntity : BaseEntity<int>
{
public override int PK { get; set; }
}
class Program
{
static void Main(string[] args)
{
var derivedEntity = new DerivedEntity();
var type = derivedEntity.GetType();
var flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty;
foreach (var memberInfo in type.GetMember("PK", flags))
开发者_C百科 {
Console.WriteLine(
"Member: " + memberInfo.Name
+ " from " + memberInfo.DeclaringType);
}
Console.WriteLine("Running : " + Environment.Version);
Console.WriteLine("mscorlib: " + typeof(int).Assembly.GetName().Version);
}
}
On the machine running 2.0.50727.4952 I see the following output:
Member: PK from MemberInfoTest.DerivedEntity
Running : 2.0.50727.4952
mscorlib: 2.0.0.0
On a machine running 2.0.50727.3615 I get different output:
Member: PK from MemberInfoTest.DerivedEntity
Member: PK from MemberInfoTest.BaseEntity`1[System.Int32]
Running : 2.0.50727.3615
mscorlib: 2.0.0.0
The above differences cause an AmbiguousMatchException
under various circumstances. Which of these behaviors is correct and is there a "fix" for the other?
EDIT: I just tested targeting the CLR-4 runtime and the abstract closed property is not returned in either case, further suggesting in my mind that the first behavior is correct.
I'm not sure why this behavior occurs. My guess is you are seeing an RTM and SP1 CLR and reflection has a subtle difference / bug between the 2 versions.
You can fix this problem by stating you want the PK
member which is declared on the specific type you are doing GetMembers
on by setting BindingFlags.DeclaredOnly
. The DeclaredOnly
will limit the return members to only those members which are declared on the specific type. It will filter out any members declared on parent types.
精彩评论