reflection大师:为什么我的MethodInfo对象不相等?

基本上,在静态System.Linq.Expressions.Expression.Bind()方法中发生的一些内部检查在我的属性上显示“方法不是属性访问器”,显然是属性。 使用Reflector,我已经最小化了导致问题的代码量,而且我不能为我的生活找出为什么会发生这种情况。 我唯一的猜测是,它与属性不属于类本身的事实有关,但我认为这应该仍然有效:

我试图用尽可能少的代码做一个小例子。 下面的代码应该完整运行。

 using System; using System.Reflection; public class Base { public virtual int Id { get; set; } } // As you can see, SubClass does not override the Id property of Base. public class SubClass : Base { } class Program { static void Main(string[] args) { // Getting the property directly from the type. PropertyInfo propertyInfo = typeof(SubClass).GetProperty("Id"); MethodInfo setMethod = propertyInfo.GetSetMethod(); /* Code from here on out is from the System.Linq.Expressions.Bind() method (the one that accepts a MethodInfo argument). This method causes GetProperty to be called and retrieve what should be the same PropertyInfo. It fails here, saying something along the lines of "Method is not a property accessor." which doesn't make sense. */ PropertyInfo propertyInfo2 = GetProperty(setMethod); } private static PropertyInfo GetProperty(MethodInfo mi) { // Not sure if it matters, but declaringType here is "Base". Type declaringType = mi.DeclaringType; BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Public; bindingAttr |= mi.IsStatic ? BindingFlags.Static : BindingFlags.Instance; foreach (PropertyInfo info in declaringType.GetProperties(bindingAttr)) { // For the "Id" property, info.CanRead is true, but CheckMethod is false. if (info.CanRead && CheckMethod(mi, info.GetGetMethod(true))) return info; // For the "Id" property, info.CanWrite is true, but CheckMethod is false. if (info.CanWrite && CheckMethod(mi, info.GetSetMethod(true))) return info; } // This gets thrown after passing by the "Id" property that is the one I'm looking for. throw new Exception("Method is not a property accessor"); } private static bool CheckMethod(MethodInfo method, MethodInfo propertyMethod) { // These are not equal, so it goes to the next check. In the debugger, they appear identical when I look through the object tree. if (method == propertyMethod) return true; Type declaringType = method.DeclaringType; return ((declaringType.IsInterface && (method.Name == propertyMethod.Name)) && (declaringType.GetMethod(method.Name) == propertyMethod)); } } 

如果有人可以提供帮助我会非常感激! 我现在非常失落。

编辑 – 如果用typeof(Base)替换typeof(SubClass) ,它可以工作,所以它与该关系有关。 我想我可以通过制作像typeof(SubClass).GetPropertyFromActualClass("Id")这样的扩展方法来解决问题,但我不确定如何执行该检查。

Base和SubClass的属性和方法信息确实不相等,即使SubClass没有自己的实现,如下所示:

 var subPropertyInfo = typeof(SubClass).GetProperty("Id"); var subPropertyInfoSetter = subPropertyInfo.GetSetMethod(); var basePropertyInfo = typeof(Base).GetProperty("Id"); var basePropertyInfoSetter = basePropertyInfo.GetSetMethod(); Console.WriteLine(subPropertyInfo == basePropertyInfo); // false Console.WriteLine(subPropertyInfoSetter == basePropertyInfoSetter); // false 

如果使用mi.ReflectedType而不是mi.DeclaringType,则检查成功:

 var type = subPropertyInfoSetter.ReflectedType; Console.WriteLine(type.GetProperty("Id").GetSetMethod() == subPropertyInfoSetter); // true