我有一个扩展方法,该方法使用动态属性对 ObservableCollection
public static List<T> OrderByField<T>(this ObservableCollection<T> observableCollection, string sortField, string sortDirection)
{
// Sort the collection based on the name of the parameter.
IQueryable<T> queryable = observableCollection.AsQueryable();
string method = sortDirection == "Asc" ? "OrderBy" : "OrderByDescending";
var parameter = Expression.Parameter(queryable.ElementType, "p");
var property = Expression.Property(parameter, sortField);
var expression = Expression.Lambda(property, parameter);
Type[] types = new Type[] { queryable.ElementType, expression.Body.Type };
var methodCallExpression = Expression.Call(typeof(Queryable), method, types, queryable.Expression, expression);
return queryable.Provider.CreateQuery<T>(methodCallExpression).ToList();
}
这在我的调试版本中效果很好,但是当我在消息中设置“ 使用.Net Native工具链编译”时,崩溃了:
类型为'System.Linq.Queryable'的通用方法'OrderBy'与提供的类型实参和实参不兼容。如果该方法是非泛型的,则不应该提供任何类型的参数。
进一步的测试表明,如果我在执行动态的“ Expression.Call ”之前显式而不是动态地调用“ OrderBy”方法,它将与 .Net Native工具一起使用链设置。因此,我将方法精简为此(这不是一个解决方法,仅说明了问题所在):
public static List<T> OrderByField<T>(this ObservableCollection<T> observableCollection, string sortField, string sortDirection)
{
// [HACK] This fixes it so that the call to Expression.Call doesn't crash.
IQueryable<T> queryable1 = new ObservableCollection<T>().AsQueryable();
Queryable.OrderBy<T, int>(queryable1, p => p.GetHashCode());
Queryable.OrderByDescending<T, int>(queryable1, p => p.GetHashCode());
// Sort the collection based on the name of the parameter.
IQueryable<T> queryable = observableCollection.AsQueryable();
string method = sortDirection == "Asc" ? "OrderBy" : "OrderByDescending";
var parameter = Expression.Parameter(queryable.ElementType, "p");
var property = Expression.Property(parameter, sortField);
var expression = Expression.Lambda(property, parameter);
Type[] types = new Type[] { queryable.ElementType, expression.Body.Type };
var methodCallExpression = Expression.Call(typeof(Queryable), method, types, queryable.Expression, expression);
return queryable.Provider.CreateQuery<T>(methodCallExpression).ToList();
}