我可以在Linq Comparable中使用TryParse吗?

某种:

Documenti = Documenti .OrderBy(o => string.IsNullOrEmpty(o.Note)) .ThenBy(o => Int32.TryParse(o.Note)) .ToList(); 

如果o.Note是“或”不是int ,那将“忽略”(不是命令,放在最后)。

我该怎么做?

使用C#7或更新版本的每个人都滚动到底部,其他人都可以阅读原始答案:


是的,如果将正确的参数传递给int.TryParse ,则可以。 这两个重载都将int作为out -parameter,并使用解析后的值将其初始化。 像这样:

 int note; Documenti = Documenti .OrderBy(o => string.IsNullOrEmpty(o.Note)) .ThenBy(o => Int32.TryParse(o.Note, out note)) .ToList(); 

干净的方法是使用一个解析为int并返回int? 如果不可解析:

 public static int? TryGetInt(this string item) { int i; bool success = int.TryParse(item, out i); return success ? (int?)i : (int?)null; } 

现在您可以使用此查询( OrderByDescending因为true是“大于”而不是false ):

 Documenti = Documenti.OrderByDescending(d => d.Note.TryGetInt().HasValue).ToList(); 

它比使用int.TryParse使用的局部变量作为out参数更int.TryParse

埃里克·利珀特(Eric Lippert)评论了我的另一个答案:

C#LINQ:字符串(“[1,2,3]”)如何解析为数组?


更新, 这已经改变了C#7 。 现在,您可以直接在使用参数的位置声明变量:

 Documenti = Documenti .OrderBy(o => string.IsNullOrEmpty(o.Note)) .ThenBy(o => Int32.TryParse(o.Note, out int note)) .ToList(); 
 int dummy; Documenti = Documenti.OrderBy( o => Int32.TryParse(o.Note, out dummy) ? dummy : Int32.MaxValue /* or Int32.MinValue */ ).ToList(); 

注意:在Int32.MaxValueInt32.MinValue之间切换会将空值放在列表的前面或末尾。

这不会产生预期的结果b / c TryParse返回bool而不是int 。 最简单的方法是创建一个返回int的函数。

 private int parseNote(string note) { int num; if (!Int32.TryParse(note, out num)) { num = int.MaxValue; // or int.MinValue - however it should show up in sort } return num; } 

从你的排序中调用该函数

 Documenti = Documenti .OrderBy(o => parseNote(o.Note)) .ToList(); 

你也可以内联它,但是,我认为一个单独的方法使代码更具可读性。 我确定编译器会内联它,如果它是一个优化。

实际上,你可以在lambda表达式中放入更复杂的逻辑:

 List Documenti = new List() { new Doc(""), new Doc("1"), new Doc("-4"), new Doc(null) }; Documenti = Documenti.OrderBy(o => string.IsNullOrEmpty(o.Note)).ThenBy(o => { int result; if (Int32.TryParse(o.Note, out result)) { return result; } else { return Int32.MaxValue; } }).ToList(); foreach (var item in Documenti) { Console.WriteLine(item.Note ?? "null"); // Order returned: -4, 1, , null } 

记住, o => Int32.TryParse(...)只是创建一个委托的简写, Int32.TryParse(...)接受o作为参数并返回Int32.TryParse(...) 。 只要它仍然是具有正确签名的语法正确方法(例如,所有代码路径返回int ),您可以使它做任何您想做的事情

C#7有一些新function,使这更容易

 var ints = from a in str.Split(',').Select(s=> new { valid = int.TryParse(s, out int i), result = i }) where a.valid select a.result; 

或者你特别要求排序

 var ints = from a in str.Split(',') orderby (int.TryParse(s, out int i) ? i : 0 ) select a.result;