我正在尝试读取一个文件,该文件本质上是一个整数列表,由一行分隔。显然,文件输入永远不可信,所以我需要过滤掉非整数。
我知道as
运算符通常会转换为if然后赋值为null,但是因为int
不可为空而不是这种情况。我想也许我可以施展到Nullable<int>
。我从未真正钻研过这个,我想也许我能做到:
var lines = File.ReadAllLines("");
var numbers = lines.Select(line => line as int?).Where(i => i != null);
我知道我可以通过以下方式解决这个问题:
var numbers = lines.Select(line =>
{
int iReturn = 0;
if (int.TryParse(line, out iReturn ))
return iReturn;
else
return null;
}).Where(i => i != null);
我也可以将其作为扩展方法。
我只是在一个陈述中寻找一种简洁明了的方式来演绎演员,并理解为什么我的代码无效。
答案 0 :(得分:3)
我总是使用这种简单的扩展方法:
public static int? TryGetInt(this string item)
{
int i;
bool success = int.TryParse(item, out i);
return success ? (int?)i : (int?)null;
}
然后很容易:
var numbers = lines.Select(line => line.TryGetInt())
.Where(i => i.HasValue)
.Select(i => i.Value);
您也可以在没有扩展名的情况下使用int.TryParse
,但这是未记录的,因此将来可能会停止工作:
int i = 0;
var numbers = lines.Where(line => int.TryParse(line, out i))
.Select(line => i);
修改
“也理解为什么我的代码无效”
相关代码:
if (int.TryParse(line, out iReturn ))
return iReturn;
else
return null;
如果您要替换
,它会起作用else
return null;
与
else
return (int?)null;
因为您要返回int
,但null
无法隐式转换为int
。
答案 1 :(得分:1)
没有一种简洁的方法可以做到这一点,因为在这里你不需要强制转换(你不能强制转换) - 你需要从一种类型转换为另一种类型。课程类型为int
和string
(因此不完全是“任何”类型),但在一般情况下,无关类型之间的任何转换都不能“就像那样”。
答案 2 :(得分:0)
不。 C#故意谨慎地将字符串更改为数字。
您可以使用foreach循环使代码更短(不再为空)
var numbers = new List<int>();
foreach(string line in lines)
{
int n;
if (int.TryParse(line, out n))
numbers.Add(n);
}
答案 3 :(得分:0)
您可以创建和扩展方法
public static int? ToInt(this string s, int default){ ... }
并在LINQ中使用它:
var lines = File.ReadAllLines(path);
var numbers = lines.Select(line => line.ToInt())
.Where(i => i != null);
答案 4 :(得分:0)
如果我理解正确并且您只想过滤非整数行,那么正则可以选择正则表达式吗?
var lines = File.ReadAllLines("");
var numbers = lines.Where(i => Regex.IsMatch(i, "[0-9]+"));
答案 5 :(得分:0)
这是我提出的最好的:
使用此扩展方法:
public static class Int32Extensions
{
public static int? ParseOrDefault(this string text)
{
int iReturn = 0;
if (int.TryParse(text, out iReturn))
{
return iReturn;
}
return null;
}
}
像这样:
var query = lines.Select(x => x.ParseOrDefault()).Where(x => x.HasValue);