4

我正在尝试读取一个文件,该文件本质上是一个整数列表,由一行分隔。显然,文件输入永远不能被信任,所以我需要过滤掉非整数。

  • 1
  • 2
  • 3
  • 4

我知道as运算符通常会在可以转换的情况下进行转换,然后分配一个空值,但是因为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);

我也有可能将其作为扩展方法。

我只是在寻找一种简洁、简洁的方式来在语句中进行强制转换,并了解为什么我的代码无效。

4

6 回答 6

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

于 2013-03-07T13:47:13.183 回答
1

没有一种简洁的方法可以做到这一点,因为在这里你不需要强制转换(你不能强制转换)——你需要从一种类型转换为另一种类型。类型当然是intand string(所以不完全是“任何”类型),但在一般情况下,不相关类型之间的任何转换都不能“像那样”完成。

于 2013-03-07T13:43:45.750 回答
0

没有。C# 在将字符串更改为数字时刻意谨慎。

您可以使用 foreach 循环使代码更短(不再有空值)

var numbers = new List<int>();

foreach(string line in lines)
{
    int n;
    if (int.TryParse(line, out n))
        numbers.Add(n);
}
于 2013-03-07T13:43:25.557 回答
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);
于 2013-03-07T13:47:34.387 回答
0

如果我理解正确并且您只想过滤非整数行,也许正则表达式是一种选择?

var lines = File.ReadAllLines("");
var numbers = lines.Where(i => Regex.IsMatch(i, "[0-9]+"));
于 2013-03-07T13:52:11.680 回答
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);
于 2013-03-07T13:55:48.113 回答