如何在LINQ查询表达式中动态设置orderby排序规则?
解决LINQ查询中动态orderby不生效的问题
问题原因
你当前的orderby sortby descending写法错误:sortby是一个Func<Book, string>委托,直接写sortby相当于把委托对象本身作为排序键,所有元素对应的委托都是同一个实例,排序逻辑被忽略,自然不会产生排序效果。
单个LINQ查询表达式的解决方法
要让排序生效,需要在orderby子句中调用委托并传入当前的book对象,用委托返回的结果作为排序键:
orderby sortby(book) descending
补充说明
关于TKey的疑问:
Func<Book, TKey>中的TKey是泛型类型参数,代表排序键的类型。你当前只需要按string类型的title或author排序,所以用Func<Book, string>完全没问题。如果以后需要支持其他类型(比如int类型的出版年份),可以将sortby声明为泛型委托,或者使用IComparer<Book>,但当前场景下Func<Book, string>足够满足需求。变量初始化问题:你的代码中
searchby和sortby没有默认值,如果用户输入的不是"a"或"b",会导致编译错误。建议给它们设置默认值,避免异常:
Func<Book, bool> searchby = _ => false; // 默认不匹配任何结果 Func<Book, string> sortby = s => s.title; // 默认按标题排序
修正后的完整代码片段
public static void Main(string[] args) { bool endapp = false; // Book是包含title、author字段的类 Func<Book, bool> searchby = _ => false; string searchterm; Func<Book, string> sortby = s => s.title; // 设置默认排序规则 while (!endapp) { List<Book> bookList = new List<Book>() { /* 初始化你的书籍列表 */ }; Console.WriteLine("Enter search term:"); searchterm = Console.ReadLine(); Console.WriteLine("Would you like to search by A:title, B: author?"); string response = Console.ReadLine()?.ToLower() ?? ""; if (response == "a") { searchby = s => s.title.Contains(searchterm); } else if (response == "b") { searchby = s => s.author.Contains(searchterm); } Console.WriteLine("Sort by A: title, B: author?"); response = Console.ReadLine()?.ToLower() ?? ""; if (response == "a") { sortby = s => s.title; } else if (response == "b") { sortby = s => s.author; } // 修正后的LINQ查询 var searchResults = from book in bookList where searchby(book) orderby sortby(book) descending select book; foreach (Book book in searchResults) { Console.WriteLine(book.title); } endapp = true; } }
内容的提问来源于stack exchange,提问作者chris.4star
相关产品推荐
相关产品推荐

