我正在深入阅读C#以尝试更好地理解语言。我之前使用简单的lambda表达式使用单个参数并熟悉它们。我努力的部分是films.Sort((f1, f2) => f1.Name.CompareTo(f2.Name));
来对列表进行排序。从我能够弄清楚当我尝试向其添加IComparer<Film>
时,lambda表达式的计算结果为f3
。被称为IComparer.Compare Method (T, T)的方法确定了项目顺序。
第二个参数让我想说它比较列表中的第N和第N + 1 film
并从0到films.Count-1
进行比较。它是否正确?如果没有,我误解了哪一部分。我不想避免错误地假设并避免意外错误。
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var films = GetFilms();
Action<Film> print = film => Console.WriteLine("Name={0}, Year={1}", film.Name, film.Year);
Console.WriteLine("All films");
films.ForEach(print);
Console.WriteLine();
Console.WriteLine("Old films");
films.FindAll(film => film.Year < 1960).ForEach(print);
Console.WriteLine();
Console.WriteLine("Sorted films");
films.Sort((f1, f2) => f1.Name.CompareTo(f2.Name));
films.ForEach(print);
}
class Film
{
public string Name { get; set; }
public int Year { get; set; }
}
static List<Film> GetFilms()
{
return new List<Film>
{
new Film { Name = "Jaws", Year = 1975 },
new Film { Name = "Singing in the Rain", Year = 1952 },
new Film { Name = "Some like it Hot", Year = 1959 },
new Film { Name = "The Wizard of Oz", Year = 1939 },
new Film { Name = "It's a Wonderful Life", Year = 1946 },
new Film { Name = "American Beauty", Year = 1999 },
new Film { Name = "High Fidelity", Year = 2000 },
new Film { Name = "The Usual Suspects", Year = 1995 }
};
}
}
答案 0 :(得分:2)
您无法从方法签名中判断参数的使用次数。我可以编写一个永远不会调用其参数的方法Foo(Func<string, string>)
。
但是,由于这是一种排序方法,因此仅在列表上迭代一次是不够的。有许多不同的排序算法,但它们倾向于使用O(n log(n))
比较。换句话说,将已排序列表的长度加倍将导致对lambda函数的调用略多于两倍。
如果您想查看运行时实际发生的情况,请添加一些日志记录!
films.Sort((f1, f2) =>
{
Console.WriteLine("Comparing ${f1.Name} to ${f2.Name}");
return f1.Name.CompareTo(f2.Name);
});
答案 1 :(得分:0)
实际上,您可以使用LINQ对任何实现IEnumerable<T>
接口的类型的元素进行排序,例如List<T>
类型:
// This will order the films by their name.
var result1 =
films
.OrderBy(film => film.Name)
.ToList();
// This will order the films first by Year in descending order and
// then by Name in ascending order.
var result2 =
films
.OrderByDescending(film => film.Year)
.ThenBy(film => film.Name)
.ToList();
您还可以使用ThenByDescending()
方法,如果需要,您还可以使用这些方法创建更长的链。
问题在于,您应该在lambda表达式中一次只选择一个属性。