4

基本的に行で区切られた整数のリストであるファイルを読み込もうとしています。明らかに、ファイル入力は決して信頼できないため、非整数を除外する必要があります。

  • 1
  • 2
  • 3
  • 4

as演算子は通常、変換できる場合は変換してからnullを割り当てますが、nullint可能ではないため、そうではありません。にキャストできるのではないかと思いました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

ここではキャストする必要がない(キャストできない)ため、これを行うための簡潔な方法はありません。あるタイプから別のタイプに変換する必要があります。もちろん、タイプはintstring(正確には「任意の」タイプではありません)ですが、一般的な場合と同様に、無関係なタイプ間の変換は「そのように」行うことはできません。

于 2013-03-07T13:43:45.750 に答える
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

いいえ。C#は、文字列を数値に変更することについて慎重に注意しています。

foreachループを使用して、コードを短くすることができます(nullはなくなります)。

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

私があなたを正しく理解していて、整数以外の行をフィルタリングしたいだけなら、おそらく正規表現がオプションですか?

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 に答える