所以我有一个IEnumerable<string>
可以包含可以解析int
为的值,以及不能的值.
如您所知,Int32.Parse
如果字符串无法更改为int,则抛出异常,同时Int32.TryParse
可用于检查并查看是否可以在不处理异常的情况下进行转换.
所以我想使用LINQ查询来解析那些可以解析为int的字符串,而不会抛出异常.我有一个解决方案,但希望社区提出有关这是否是最佳方法的建议.
这就是我所拥有的:
int asInt = 0;
var ints = from str in strings
where Int32.TryParse(str, out asInt)
select Int32.Parse(str);
Run Code Online (Sandbox Code Playgroud)
所以你可以看到,我正在使用它asInt
作为调用的临时空间TryParse
,只是为了确定是否TryParse
会成功(返回bool).然后,在投影中,我实际上正在执行解析.那感觉很难看.
这是使用LINQ过滤单行中的可解析值的最佳方法吗?
Jon*_*eet 83
在查询语法中很难做到这一点,但在lambda语法中它并不算太糟糕:
var ints = strings.Select(str => {
int value;
bool success = int.TryParse(str, out value);
return new { value, success };
})
.Where(pair => pair.success)
.Select(pair => pair.value);
Run Code Online (Sandbox Code Playgroud)
或者,您可能会发现值得编写一个返回以下内容的方法int?
:
public static int? NullableTryParseInt32(string text)
{
int value;
return int.TryParse(text, out value) ? (int?) value : null;
}
Run Code Online (Sandbox Code Playgroud)
然后你可以使用:
var ints = from str in strings
let nullable = NullableTryParseInt32(str)
where nullable != null
select nullable.Value;
Run Code Online (Sandbox Code Playgroud)
Joe*_*nos 13
它仍然是两个代码行,但你可以稍微缩短你的原始代码:
int asInt = 0;
var ints = from str in strings
where Int32.TryParse(str, out asInt)
select asInt;
Run Code Online (Sandbox Code Playgroud)
由于TryParse已经在select时运行asInt
,因此填充变量,因此您可以将其用作返回值 - 您无需再次解析它.
如果你不介意你的同事在停车场跳你,有一种方法可以用一个真正的linq(没有分号)来做到这一点....
strings.Select<string, Func<int,int?>>(s => (n) => int.TryParse(s, out n) ? (int?)n : (int?)null ).Where(? => ?(0) != null).Select(? => ?(0).Value);
Run Code Online (Sandbox Code Playgroud)
这是不切实际的,但在一个声明中这样做是一个非常有趣的挑战.
我可能在某个地方有这个小实用方法(我实际上在我当前的代码库中这样做了 :-))
public static class SafeConvert
{
public static int? ToInt32(string value)
{
int n;
if (!Int32.TryParse(value, out n))
return null;
return n;
}
}
Run Code Online (Sandbox Code Playgroud)
然后你使用这个更干净的 LINQ 语句:
from str in strings
let number = SafeConvert.ToInt32(str)
where number != null
select number.Value;
Run Code Online (Sandbox Code Playgroud)
我同意使用额外的变量感觉很丑。
根据Jon 的回答并更新到 C# 7.0 解决方案,我们可以使用新var out
功能:(不会短很多,但不需要内部作用域或查询外临时变量)
var result = strings.Select(s => new { Success = int.TryParse(s, out var value), value })
.Where(pair => pair.Success)
.Select(pair => pair.value);
Run Code Online (Sandbox Code Playgroud)
以及命名元组:
var result = strings.Select(s => (int.TryParse(s, out var value), value))
.Where(pair => pair.Item1)
.Select(pair => pair.value);
Run Code Online (Sandbox Code Playgroud)
或者,如果建议在查询语法中使用它的方法:
public static int? NullableTryParseInt32(string text)
{
return int.TryParse(text, out var value) ? (int?)value : null;
}
Run Code Online (Sandbox Code Playgroud)
我还想建议一种无需额外方法的查询语法,但如以下链接中所述,out var
c# 7.0 不支持并导致编译错误:
查询子句中不允许使用 Out 变量和模式变量声明
链接:查询表达式中的表达式变量
通过这是一项 C# 7.0 功能,人们可以让它在早期的 .NET 版本上工作:
归档时间: |
|
查看次数: |
37201 次 |
最近记录: |