我习惯于在不使用 Linq 或 Lambda 语句的情况下编写 C#,但我想提高我的理解。我有看起来像这样用 C# 2.0 编写的带有foreach
循环的代码:
List<string> strings = new List<string>();
strings.Add("1");
strings.Add("blah");
List<int> ints1 = new List<int>();
foreach (string x in strings)
{
int r;
if (int.TryParse(x, out r))
ints1.Add(r);
}
它正在执行一项简单的任务 - 从字符串列表中填充整数列表,忽略任何实际上不是整数的内容。在我有限的经验中,Linq 和 Lambda 语句似乎能够将 foreach 语句缩减为非常简洁易读的方式来做同样的事情。所以我想我会用 C# 3.0 试试这个小家伙。但我能想到的最好的是:
IEnumerable<int> ints2 = strings.Select(x =>
{
int r;
if (int.TryParse(x, out r))
return r as int?;
return null;
})
.Where<int?>(x => x != null)
.Select(x => x.Value);
呸!我找不到将转换和过滤结合在一个呼叫中的方法,最终得到的结果似乎比原来的要糟糕得多。有没有办法做到这一点,还是我应该坚持我的 foreach?
编辑:总结调查结果,如果您使用的是 .NET 4.0,这里有两种使用 LINQ 的方法:
IEnumerable<int> ints1 = strings
.Where(x => new Int32Converter().IsValid(x))
.Select(x => int.Parse(x));//Broken in .NET 3.5 due to bug in Int32Converter
IEnumerable<int> int2 = strings
.Where(x => { int r; return int.TryParse(x, out r); })
.Select(x => int.Parse(x));
第二种方法更快,并且在 .NET 3.5 中没有损坏。根据接受的答案,可能没有理由不将其放入扩展方法中,而不是 foreach。请参阅连接问题以了解该Int32Converter
错误。