目前,如果我们将订购方向作为外部依赖关系,我们必须使用 if 来应用此方向:
public static IEnumerable<FileInfo> getlist(string directory, string searchPattern, string order)
{
var files = new DirectoryInfo(directory).EnumerateFiles(searchPattern);
if (order == "A")
return files.OrderBy(f => f.CreationTime);
return files.OrderByDescending(f => f.CreationTime);
}
为什么 OrderBy 没有超载将订单方向作为参数? 在Reflector中,我发现它或多或少是在内部实现的,但由于一些奇怪的原因而没有暴露出来。
我更愿意写这样的东西:
public static IEnumerable<FileInfo> getlist(string directory, string searchPattern, string order)
{
return new DirectoryInfo(directory)
.EnumerateFiles(searchPattern)
.OrderBy(f => f.CreationTime, order == "A" ? SortOrder.Ascending : SortOrder.Descending);
}
更新
我自己可以写这个,只是希望它已经在框架中了:
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
ListSortDirection order)
{
switch (order)
{
case ListSortDirection.Ascending: return source.OrderBy(keySelector);
case ListSortDirection.Descending: return source.OrderByDescending(keySelector);
}
throw new ArgumentOutOfRangeException("order");
}
答案 0 :(得分:7)
由于SortOrder
枚举在技术上可以采用超过2个值(想象(SortOrder) 35
),因此它不会完全捕获二元性。有两种方法可以确保没有歧义或需要进行范围检查(你的例子btw中缺少这种方法)。
那就是说,这是你想要的方法:
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
SortOrder order)
{
if(order < SortOrder.Ascending || order > SortOrder.Descending)
{
throw new ArgumentOutOfRangeException("order");
}
return order == SortOrder.Ascending
? source.OrderBy(keySelector)
: source.OrderByDescending(keySelector);
}
答案 1 :(得分:5)
OrderBy
方法已具备您需要的灵活性,以及更多,因为它可以采用可选的IComparer<T>
参数:
return new DirectoryInfo(directory)
.EnumerateFiles(searchPattern)
.OrderBy(f => f.CreationTime, order == "A"
? Comparer<DateTime>.Default
: new DescendingComparer<DateTime>);
// ...
public DescendingComparer<T> : Comparer<T>
{
public override int Compare(T x, T y)
{
return Comparer<T>.Default.Compare(y, x);
}
}
答案 2 :(得分:3)
我不知道为什么。虽然,在某些时候,你可以自己做。
public static class IEnumerableSortExtension
{
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
SortOrder order)
{
if (order == SortOrder.Ascending)
return this.OrderBy(keySelector);
else if (order == SortOrder.Descending)
return this.OrderByDescending(keySelector);
throw new InvalidOperationException(); // do something better than this
}
}
答案 3 :(得分:2)
其他答案比我的学术更具学术性,但如果你需要快速和肮脏,那么你可以这样做:
var files = new DirectoryInfo(directory)
.EnumerateFiles(searchPattern)
.OrderByDescending(f => f.CreationTime);
if (order == "A")
files = files.Reverse();
return files;