对类型 T 的可观察集合进行排序,其中 T 将在 运行 时间发生变化(泛型)
Sort an observable collection of type T where T will change on run time (generics)
您好,我想对 ObservableCollection 进行排序,但无法访问其属性。
public static class CommonMethods<T>
{
public static ObservableCollection<T> Sort(ObservableCollection<T> array, string columnName, bool sort)
{
ObservableCollection<T> res = new ObservableCollection<T>();
res = res.OrderBy(r => r[""]) // This gives an error says cannot apply indexing with [] to an expression of type T.
return res;
}
}
调用代码。
mlRegionDetails = CommonMethods<MLRegion>.Sort(mlRegionDetails, columnName, sort);
请告诉我哪里错了。
不要传递您要排序的 属性 的名称,而是传递选择器函数:
public static ObservableCollection<T> Sort(ObservableCollection<T> array, Func<T, object> columnSelector, bool sort)
{
ObservableCollection<T> res = new ObservableCollection<T>(array.OrderBy(columnSelector));
return res;
}
并使用以下方式调用它:
mlRegionDetails = CommonMethods<MLRegion>.Sort(mlRegionDetails, x => x.SomeColumn, sort);
如果要使用 string
s 执行此操作,则需要手动构建表达式。
注意:以下代码在此处编写时尚未经过测试,可能需要进行一些更改。
public static class CommonMethods<T>
{
private static readonly MethodInfo orderByMethod =
typeof(Enumerable).GetMethods().Single(method =>
method.Name == nameof(Enumerable.OrderBy) && method.GetParameters().Length == 2);
public static ObservableCollection<T> Sort(ObservableCollection<T> array, string columnName, bool sort)
{
var tType = typeof(T);
var parameter = Expression.Parameter(tType);
Expression member = Expression.Property(parameter, columnName);
var lambda = Expression.Lambda(member, paramter);
var genericMethod = orderByMethod.MakeGenericMethod(tType, member.Type);
var orderedData = genericMethod.Invoke(null, new object[] { array, lambda }) as IEnumerable<T>;
return new ObservableCollection<T>(orderedData);
}
}
最后我找到了解决问题的替代方法。我创建了一个临时变量,然后将该 ObservableCollection 转换为 AsEnumerable 并通过传递给它的键对其进行排序。
创建关键部分归功于@Camilo Terevinto
public static class CommonMethods
{
public static ObservableCollection<T> sort<T>(ObservableCollection<T> array, Func<T, object> key)
{
var res = array.AsEnumerable().OrderByDescending(key); ;
ObservableCollection<T> temp = new ObservableCollection<T>(res);
return temp;
}
}
您好,我想对 ObservableCollection 进行排序,但无法访问其属性。
public static class CommonMethods<T>
{
public static ObservableCollection<T> Sort(ObservableCollection<T> array, string columnName, bool sort)
{
ObservableCollection<T> res = new ObservableCollection<T>();
res = res.OrderBy(r => r[""]) // This gives an error says cannot apply indexing with [] to an expression of type T.
return res;
}
}
调用代码。
mlRegionDetails = CommonMethods<MLRegion>.Sort(mlRegionDetails, columnName, sort);
请告诉我哪里错了。
不要传递您要排序的 属性 的名称,而是传递选择器函数:
public static ObservableCollection<T> Sort(ObservableCollection<T> array, Func<T, object> columnSelector, bool sort)
{
ObservableCollection<T> res = new ObservableCollection<T>(array.OrderBy(columnSelector));
return res;
}
并使用以下方式调用它:
mlRegionDetails = CommonMethods<MLRegion>.Sort(mlRegionDetails, x => x.SomeColumn, sort);
如果要使用 string
s 执行此操作,则需要手动构建表达式。
注意:以下代码在此处编写时尚未经过测试,可能需要进行一些更改。
public static class CommonMethods<T>
{
private static readonly MethodInfo orderByMethod =
typeof(Enumerable).GetMethods().Single(method =>
method.Name == nameof(Enumerable.OrderBy) && method.GetParameters().Length == 2);
public static ObservableCollection<T> Sort(ObservableCollection<T> array, string columnName, bool sort)
{
var tType = typeof(T);
var parameter = Expression.Parameter(tType);
Expression member = Expression.Property(parameter, columnName);
var lambda = Expression.Lambda(member, paramter);
var genericMethod = orderByMethod.MakeGenericMethod(tType, member.Type);
var orderedData = genericMethod.Invoke(null, new object[] { array, lambda }) as IEnumerable<T>;
return new ObservableCollection<T>(orderedData);
}
}
最后我找到了解决问题的替代方法。我创建了一个临时变量,然后将该 ObservableCollection 转换为 AsEnumerable 并通过传递给它的键对其进行排序。
创建关键部分归功于@Camilo Terevinto
public static class CommonMethods
{
public static ObservableCollection<T> sort<T>(ObservableCollection<T> array, Func<T, object> key)
{
var res = array.AsEnumerable().OrderByDescending(key); ;
ObservableCollection<T> temp = new ObservableCollection<T>(res);
return temp;
}
}