我不太确定我是否理解如何正确使用C#中的泛型。说我有以下方法。我想允许它在任何类型的列表上工作。目前我有List其中Row是一个自定义结构,我想重用这个排序方法为我做的六个结构。我以为我可以在返回类型和参数类型中执行List<T>
,但它不喜欢它。
public static List<Row> SortResults( List<Row> listRow, string sortColumn, bool ascending)
{
switch (ascending)
{
case true:
return (from r in listRow
orderby r.GetType().GetField(sortColumn).GetValue(r)
select r).ToList<Row>();
case false:
return (from r in listRow
orderby r.GetType().GetField(sortColumn).GetValue(r) descending
select r).ToList<Row>();
default:
return listRow;
}
}
答案 0 :(得分:8)
嗯,这是您的原始代码通用:
public static List<T> SortResults<T>(List<T> listRow,
string sortColumn, bool ascending)
{
switch (ascending)
{
case true:
return (from r in listRow
orderby r.GetType().GetField(sortColumn).GetValue(r)
select r).ToList();
case false:
return (from r in listRow
orderby r.GetType().GetField(sortColumn).GetValue(r) descending
select r).ToList();
default:
return listRow;
}
}
注意我是如何从ToList
调用中删除类型参数的 - 让编译器解决它:)
(顺便说一下,我不知道为什么编译器需要default
这里的情况。也许它总是假定会有未列出的潜在价值。)
然而,这可以更好:
public static List<T> SortResults<T>(List<T> listRow,
string sortColumn,
bool ascending)
{
FieldInfo field = typeof(T).GetField(sortColumn);
Func<T, object> projection = t => field.GetValue(t);
IEnumerable<T> sequence = ascending ? listRow.OrderBy(projection)
: listRow.OrderByDescending(projection);
return sequence.ToList();
}
这仍然是相当低效的(因为它使用反射),但至少它没有为每个项目分别获得FieldInfo
。如果想要更好的性能,可以使用通用帮助器类型来缓存委托,将值映射到每个字段的字段值,然后在方法开始时获取该委托一次。肯定会有更多的工作,但我希望它会快一个数量级。
答案 1 :(得分:2)
public static List<T> SortResults( List<T> listObject, string sortColumn, bool ascending) where T: class
然后你的ToList将是ToList<T>();
T表示您的实体/对象类型。
答案 2 :(得分:1)
您需要使方法本身通用:
public static List<Row> SortResults<Row>( List<Row> listRow, ...
^^^^^