.net - 具有属性继承的表达式树导致参数异常

标签 .net linq expression-trees

关注这篇文章:link text我正在尝试创建一个引用属性的表达式树。我的代码如下所示:

public interface IFoo
{
    void X {get;set;}
}

public interface IBar : IFoo
{
    void Y {get;set;}
}

public interface IFooBarContainer
{
    IBar Bar {get;set;}
}

public class Filterer
{
     //Where T = "IFooBarContainer"
     public IQueryable<T> Filter<T>(IEnumerable<T> collection)
     {
              var argument = Expression.Parameter(typeof (T), "item");

              //...

               //where propertyName = "IBar.X";
               PropertyOfProperty(argument, propertyName); 
     }

        private static MemberExpression PropertyOfProperty(Expression expr, string propertyName)
        {
            return propertyName.Split('.').Aggregate<string, MemberExpression>(null, (current, property) => Expression.Property(current ?? expr, property));
        }
}

我收到异常:

System.ArgumentException: Instance property 'X' is not defined for type 'IBar'



ReSharper 将上面链接中的代码转换为我示例中的简明语句。两种形式的方法都返回相同的错误。

如果我引用 IBar.Y该方法不会失败。

最佳答案

您尝试访问的属性不是 IBar.X ,它是 IFoo.X . Expression.Property方法需要声明属性的实际类型,而不是子类型。如果您不相信,请尝试:

var prop = typeof(IBar).GetProperty("X");

它返回 null (仅因为 IBar 是一个接口(interface);它适用于一个类)

我认为使其工作的最简单方法是创建一个辅助方法来解析实际属性,方法是递归地向上走类型层次结构:
private PropertyInfo GetProperty(Type type, string propertyName)
{
    PropertyInfo prop = type.GetProperty(propertyName);
    if (prop == null)
    {
        var baseTypesAndInterfaces = new List<Type>();
        if (type.BaseType != null) baseTypesAndInterfaces.Add(type.BaseType);
        baseTypesAndInterfaces.AddRange(type.GetInterfaces());
        foreach(Type t in baseTypesAndInterfaces)
        {
            prop = GetProperty(t, propertyName);
            if (prop != null)
                break;
        }
    }
    return prop;
}

然后你可以重写你的PropertyOfProperty如下 :
private static MemberExpression PropertyOfProperty(MemberExpression expr, string propertyName)
{
    return propertyName
               .Split('.')
               .Aggregate<string, MemberExpression>(
                   expr,
                   (current, property) =>
                       Expression.Property(
                           current,
                           GetProperty(current.Type, property)));
}

关于.net - 具有属性继承的表达式树导致参数异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2496256/

相关文章:

c# - 使用 LINQ to SQL 读取大表 : Running out of memory vs slow paging

c# - Fast FileSize 与 Linq 比较

c# - 构建表达式树来表示 if-else

c# - 使用 linq 过滤分层列表

.net - 如何防止聊天应用中的 SCSS -vb.net

c# - 如何检查 MemoryStream 是否可以在 .NET 中转换为位图?

vb.net - 带有 Linq 语句的 XML 文字

c# - 获取远程服务器的准确时间

.net - 是否应该将针对开发人员的异常消息本地化?

c# - 从代码访问 Expression.DebugView