C# 如何使用表达式根据继承的接口属性对集合进行排序

C# 如何使用表达式根据继承的接口属性对集合进行排序,c#,expression-trees,C#,Expression Trees,这个问题在一定程度上已经在这个问题上被讨论过了:但也许我没有找到答案,或者它有微妙的不同 我有以下可查询的扩展方法: public static IQueryable<TSource> OrderByPropertyDescending<TSource>(IQueryable<TSource> source, string propertyName) { var sourceType = typeof (TSource);

这个问题在一定程度上已经在这个问题上被讨论过了:但也许我没有找到答案,或者它有微妙的不同

我有以下可查询的扩展方法:

public static IQueryable<TSource> OrderByPropertyDescending<TSource>(IQueryable<TSource> source, string propertyName)
    {
        var sourceType = typeof (TSource);
        var parameter = Expression.Parameter(sourceType, "item");
        var orderByProperty = Expression.Property(parameter, propertyName);
        var orderBy = Expression.Lambda(orderByProperty, new[] { parameter });
        return Queryable.OrderByDescending(source, (dynamic) orderBy);
    }
然后,以下方法也可以起作用:

var queryable = new List<ICreated>().AsQueryable();
var result = queryable.OrderByPropertyDescending("Created").ToList();
那么以下操作将失败:

var queryable = new List<ITimestamped>().AsQueryable();
var result = queryable.OrderByPropertyDescending("Created").ToList();
var queryable=new List().AsQueryable();
var result=queryable.OrderByPropertyDescending(“Created”).ToList();

与另一个问题的错误消息类似:未为ITimestamped类型定义实例属性“Created”。我假设我需要在接口的声明类型上找到属性(我可以通过对源类型进行爬网来实现),但是我该如何处理它呢?我尝试过的大多数尝试都会导致不正确的原始源类型无法强制转换回IQueryable。我需要在某处使用ConvertType呼叫吗?谢谢。

我会使用另一个Expression.Property()方法,它接受propertyInfo,例如

public static IQueryable<TSource> OrderByPropertyDescending<TSource>(IQueryable<TSource> source, string propertyName)
{
    var sourceType = typeof (TSource);
    var parameter = Expression.Parameter(sourceType, "item");
    var propertyInfo = FindMyProperty(sourceType, propertyName);
    var orderByProperty = Expression.Property(parameter, propertyInfo);
    var orderBy = Expression.Lambda(orderByProperty, new[] { parameter });
    return Queryable.OrderByDescending(source, (dynamic) orderBy);
}

private static PropertyInfo FindMyProperty(Type type, string propertyName)
{
    return type.GetProperty(propertyName);
}
免责声明!
这绝不是从类型获取属性的最佳方法,但它应该适用于您的情况。你应该搜索一下,找到一个满足你所有要求的FindMyProperty实现:)

先生,你真是个天才,你让我开心!工作是一种享受,我会按照你的建议寻找一种“好”的方式来获取房产信息。我很高兴我能帮上忙:)
public interface ITimestamped : ICreated
{
     ...
}
var queryable = new List<ITimestamped>().AsQueryable();
var result = queryable.OrderByPropertyDescending("Created").ToList();
public static IQueryable<TSource> OrderByPropertyDescending<TSource>(IQueryable<TSource> source, string propertyName)
{
    var sourceType = typeof (TSource);
    var parameter = Expression.Parameter(sourceType, "item");
    var propertyInfo = FindMyProperty(sourceType, propertyName);
    var orderByProperty = Expression.Property(parameter, propertyInfo);
    var orderBy = Expression.Lambda(orderByProperty, new[] { parameter });
    return Queryable.OrderByDescending(source, (dynamic) orderBy);
}

private static PropertyInfo FindMyProperty(Type type, string propertyName)
{
    return type.GetProperty(propertyName);
}
private static PropertyInfo FindMyProperty(Type type, string propertyName)
{
    var result = type.GetProperty(propertyName);
    if (result == null)
    {
        foreach(var iface in type.GetInterfaces())
        {
            var ifaceProp = FindMyProperty(iface, propertyName);
            if (ifaceProp != null)
                return ifaceProp;
        }

    }
    return result;
}