我有一个可以使用通用OrderBy参数
的泛型类该课程如下
class abc<T> where T : myType
{
public abc(....., orderBy_Argument ){ ... }
void someMethod(arg1, arg2, bool afterSort = false)
{
IEnumerable<myType> res ;
if ( afterSort && orderBy_Argument != null )
res = src.Except(tgt).OrderBy( .... );
else
res = src.Except(tgt);
}
}
orderBy可以是各种类型的
e.g。
.OrderBy( person => person.FirstName )
.OrderBy( person => person.LastName )
.OrderBy( person => person.LastName, caseInsensitive etc )
目标是使orderBy成为一个参数,而不是在
中烘焙它任何想法?
答案 0 :(得分:1)
只需将排序键作为委托传递:
class abc<T, TSort> where T : myType
{
public abc(....., Func<T, TSort> sortKeySelector ){ ... }
void someMethod(arg1, arg2, bool afterSort = false)
{
IEnumerable<myType> res ;
if ( afterSort && sortKeySelector != null )
res = src.Except(tgt).OrderBy(sortKeySelector);
else
res = src.Except(tgt);
}
}
缺点是需要额外的类型参数......
答案 1 :(得分:1)
不要将参数传递给OrderBy
传递函数,该函数会转换IEnumerable
(或IQueryable
,因为它可能会)。< / p>
修改您的示例会导致以下程序:
using System;
using System.Collections.Generic;
using System.Linq;
class abc<T> {
Func<IEnumerable<T>,IEnumerable<T>> sorter;
public abc(Func<IEnumerable<T>,IEnumerable<T>> sorter) {
this.sorter=sorter ?? (x=>x);
}
public void someMethod(IEnumerable<T> src, bool afterSort = false) {
var res= (afterSort?sorter:x=>x) (src.Skip(5).Take(10));
Console.WriteLine(string.Join(", ",res.Select(el=>el.ToString()).ToArray()));
}
}
public class Program {
static void Main() {
var strs = Enumerable.Range(0,1000).Select(i=>i.ToString());
var myAbc = new abc<string>(
xs=>xs.OrderByDescending(x=>x.Length).ThenByDescending(x=>x.Substring(1))
);
myAbc.someMethod(strs); //5, 6, 7, 8, 9, 10, 11, 12, 13, 14
myAbc.someMethod(strs,true); //14, 13, 12, 11, 10, 5, 6, 7, 8, 9
}
}
当然,这是一个非常奇怪的排序和一个荒谬的someMethod
- 但它表明你可以传递一个非常灵活的排序委托(事实上,委托可以做的不仅仅是排序)只有一个非常简短的实施。