本文介绍了大师的思考:为什么不是我的MethodInfo对象平等吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上,一些内部检查发生在静态 System.Linq.Ex pressions.Ex pression.Bind()办法说方法是不是一个属性访问我的财产,这显然是一个属性。使用反射器,我最小的code导致问题的数量,我不能为我的生命弄清楚为什么会发生这种事。我唯一​​的猜测是,它是与一个事实,即属性不是类本身,但我认为这应该仍然工作:

Basically, some internal check that happens in the static System.Linq.Expressions.Expression.Bind() method says "Method is not a property accessor" on my property that is clearly a property. Using Reflector, I've minimized the amount of code causing the problem, and I can't for the life of me figure out why this would happen. My only guess is that it has something to do with the fact that the property isn't on the class itself, but I would think this should still work:

我试图做一个小例子用最少的code可能。在code以下应全部运行。

I've tried to make a small example with the least amount of code possible. The code below should run in its entirety.

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));
    }
}

如果有人可以帮助我将不胜AP preciate吧!我非常在这一点上失去了。

If anyone could help I would greatly appreciate it! I'm very much lost at this point.

编辑 - 如果你替换 typeof运算(子类)的typeof(基地),它的工作原理,所以它的东西有关这种关系。我想我可以在根通过一个扩展方法,比如 typeof运算(子类)削减问题关闭.GetPropertyFromActualClass(ID),但我不知道如何执行查收。

Edit - If you substitute typeof(SubClass) with typeof(Base), it works, so it's something related to that relationship. I guess I could cut the issue off at the root by making an extension method like typeof(SubClass).GetPropertyFromActualClass("Id") but I'm not sure how to perform that check.

推荐答案

基地和子类的属性和方法的相关信息确实是不相等的,即使SubClass中没有自己的实现,因为在这里可以看到:

The property and method infos of Base and SubClass are indeed not equal, even if SubClass has no own implementation, as can be seen here:

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,检查成功:

If you use mi.ReflectedType instead of mi.DeclaringType, the check succeeds:

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

这篇关于大师的思考:为什么不是我的MethodInfo对象平等吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-17 01:35