基本上,静态 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(SubClass)
替换 typeof(Base)
,它会起作用,所以它与这种关系有关。我想我可以通过创建像 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
关于c# - 反射(reflection)大师 : Why aren't my MethodInfo objects equal?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8431866/