我可以在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.MaxValue
和Int32.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;