C#Linq/Lambda表达式:如何从字符串中选择一个整数?

Joe*_*orn 4 c# linq linq-to-objects

我认为解释我的问题的最好方法是使用简短的(通用的)linq-to-objects代码示例:

IEnumerable<string> ReadLines(string filename)
{
    string line;
    using (var rdr = new StreamReader(filename))
        while ( (line = rdr.ReadLine()) != null)
           yield return line;
}

IEnumerable<int> XValuesFromFile(string filename)
{
    return ReadLines(filename)
               .Select(l => l.Substring(3,3))
               .Where(l => int.TryParse(l))
               .Select(i => int.Parse(i));
}
Run Code Online (Sandbox Code Playgroud)

请注意,此代码解析整数两次.我知道我错过了一种明显的简单方法来安全地消除其中一个呼叫(因为我之前已经完成了).我现在找不到它.我怎样才能做到这一点?

Mar*_*ell 9

怎么样:

int? TryParse(string s)
{
    int i;
    return int.TryParse(s, out i) ? (int?)i : (int?)null;
}
IEnumerable<int> XValuesFromFile(string filename)
{
    return from line in ReadLines(filename)
           let start = line.Substring(3,3)
           let parsed = TryParse(start)
           where parsed != null
           select parsed.GetValueOrDefault();
}
Run Code Online (Sandbox Code Playgroud)

如果你愿意,你可以组合第二/第三行:

    return from line in ReadLines(filename)
           let parsed = TryParse(line.Substring(3,3))
Run Code Online (Sandbox Code Playgroud)

之所以选择GetValueOrDefault是因为它会跳过执行(int).Value执行的验证检查- 即它(不是那么轻微)更快(我们已经检查过它不是null).