我是一个有用的助手,可以翻译文本。
我有一个问题,我允许用户选择对列表进行排序的标准。
假设我的列表叫做:
List<Cars> AllCars = new List<Cars>;
allCars = //call the database and get all the cars
我现在想要对这个列表进行排序。
allCars.orderBy(registrationDate)
我知道上面的代码不起作用,但我不知道应该在括号里放什么。
allCars.OrderBy(c => c.RegistrationDate);
Enumerable.OrderBy
的声明是:public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector
)
而且,由于它是一个扩展方法,因此可以这样调用
source.OrderBy(keySelector).
你的 List<Car>
扮演着 source
的角色,因为它实现了 List<T> : IEnumerable<T>
。第二个参数更有趣,也是你感到困惑的地方。它被声明为类型为
Func<TSource, TKey>
这意味着它是一个委托,接受 TSource
的实例(在您的情况下为 Car
),并返回 TKey
的实例;由您决定 TKey
是什么。您已经说明了您想按 Car.registrationDate
排序,因此听起来 TKey
是 DateTime
。现在,我们如何获得其中一个委托?
在旧时代,我们可以说
DateTime GetRegistrationDate(Car car) {
return car.registrationDate;
}
并使用以下方式的OrderBy
:
allCars.OrderBy(GetRegistrationDate).
allCars.OrderBy(delegate(Car car) { return car.registrationDate; });
然后,在C# 3.0中,我们获得了使用lambda表达式的能力,这是一种非常特殊的匿名委托,具有紧凑的符号表示法。
allCars.OrderBy(car => car.registrationDate);
c => c.registrationDate
是一个 lambda 表达式,它表示一个 Func<Car, DateTime>
,可以用作 Enumerable.OrderBy
的第二个参数。
这个代码不起作用的原因是因为
allCars.orderBy(registrationDate)
registrationDate
不是一个委托。实际上,没有任何上下文,registrationDate
对编译器来说毫无意义。它不知道你是指Car.registrationDate
还是可能是指ConferenceAttendee.registrationDate
或其他什么东西。这就是为什么你必须向编译器提供额外的上下文,并告诉它你想要属性Car.registrationDate
。为此,你可以使用三种上述方法之一中的委托。
Cars
列表,因此Cars
类型必须具有公共的RegistrationDate属性或字段以进行排序。 - Mark Seemann