2

私はlinqを初めて使用しますが、これはnullボリュームフィールドでポップし続けます。ファイルは予測不可能であり、発生するので、例外がある場所に 0 を入れたいと思います。それを行うための迅速かつ簡単な方法はありますか?

     var qry =
            from line in File.ReadAllLines("C:\\temp\\T.txt")
            let myRecX = line.Split(',')
            select new myRec()

            {

               price =   Convert.ToDecimal( myRecX[0].Replace("price =  ", "")) ,
               volume = Convert.ToInt32(myRecX[1].Replace("volume =", "")),
                dTime = Convert.ToDateTime( myRecX[2].Replace("timestamp =", ""))

            };
4

3 に答える 3

4

受信データがnull、空、または完全に空白文字で構成されている場合にデフォルトを使用する場合は、次のように実行できます。

volume = string.IsNullOrWhitesplace(myRecX[1])
       ? defaultVolume // <<== You can use any constant here
       : Convert.ToInt32(myRecX[1].Replace("volume =", ""))

ただし、これは、名前付きパラメーターの位置がハードコーディングされたままであるため、必要なものを実現するための「手早く汚い」方法です。より堅牢な方法は、ファイルで指定された属性の名前を空の文字列に置き換えるのではなく、それらに注意を払うミニパーサーを作成することです。

于 2013-03-22T18:20:31.510 に答える
0

ここには、の使用以外にも問題があると思いますLinq

一般に、ファイルデータをサニタイズする前に操作することは悪い習慣です。

次の質問が(内容ではなく)ファイル名にある場合は、入力のサニタイズの概念を理解するための良い出発点です。

C#サニタイズファイル名

結局のところ、自分のコードにはファイルコンテンツの制御が欠けていると自分で言っているので、呼び出す前に:

let myRecX = line.Split(',')

次のようなプライベートメソッドを定義することをお勧めします。

string SanitizeInputLine(string input) {
  // here do whatever is needed to bring back input to 
  // a valid format in a way that subsequent calls will not
  // fail

  return input;
}

適用は簡単です。

let myRecX = SanitizeInputLine(line).Split(',')

原則として、入力を信頼することはありません。

ハワード/ルブランによる安全なコードの記述の_AllInputIs Evil!__という名前の第10章を引用させてください。

...データが検証されるまで、データを信頼しないでください。そうしないと、アプリケーションが脆弱になります。または、別の言い方をすれば、他の方法で証明されるまで、すべての入力は悪です。

于 2013-03-22T18:45:22.140 に答える
0

あなたが望むものを書くための表現力豊かな方法を提供する、このようなものを使うことができます:

static TOutput Convert<TInput, TOutput>(
    TInput value,
    params Func<TInput, TOutput>[] options)
{
    foreach (var option in options) {
        try { return option(value); }
        catch { }
    }

    throw new InvalidOperationException("No option succeeded.");
}

次のように使用します。

select new myRec()
{
   price = Convert(myRecX[0].Replace("price =  ", ""),
                   input => Convert.ToDecimal(input),
                   or => 0M),
   ...
};

関数の間接化と暗黙的な配列の構築により、パフォーマンスがわずかに低下する可能性がありますが、可能な変換の数を指定するための適切な構文が提供され、最初に成功した変換が取得されます。

于 2013-03-22T18:35:19.043 に答える