2017-04-26 4 views
0

catchブロックでオブジェクトを使用したい場合は、tryブロックで例外が発生します。私はintにいくつかの文字列を解析しており、不可能であるときに例外をキャッチする必要があり、どのオブジェクトが間違っていて、どの行にあるのかを確認する必要があります。それは可能かどうか?キャッチの試行からオブジェクトを使用する方法 - C#

いくつかのコード例です。ありがとう。

static void Main(string[] args) 
{ 
    var result = Parse(new List<string>() { "3;5;7", "qwe;3;70" }); 
} 

public static List<int[]> Parse(List<string> list) 
{ 
    try 
    { 
     return list.Select(str => str.Split(';')) 
      .Select(str => Tuple.Create(int.Parse(str[0]), int.Parse(str[1]), int.Parse(str[2]))) 
      /// something happening 
      .ToList(); 
    } 
    catch 
    { 
     //here in braces I want to know, which element was wrong 
     //"qwe" and whole line "qwe;3;70" 
     throw new FormatException($"Wrong line [{}]"); 
    } 
} 
+3

実際の 'Exception'オブジェクトを使用して必要なものすべてを手に入れることはできませんか? 'catch(Exception ex)'そしてcatchブロックの 'ex'変数を使って例外に関する情報を提供します。忘れてはならないことは、可能な限り例外タイプを特定して捕捉することです。たとえば、まずNullReferenceExceptionをキャッチしてから、最後にジェネリックなExceptionを最後に実行してみてください。 – gmiley

+3

@gmiley例外は、解析に失敗した行のインデックスを持ちません。 – Servy

+5

通常のfor-loopを使用し、try/catchのスコープ外に3つの文字列変数を作成し、それぞれの値を抽出して解析し、失敗した場合は変数 –

答えて

1

try/catchブロックの外側のラインと値項目カウンタを宣言し、LINQ式本体でそれらを増やします。

public static List<int[]> Parse(List<string> list) 
{ 
    int line = 0; 
    int item = 0; 
    try 
    { 
     return list 
      .Select(str => { 
       line++; 
       item = 0; 
       return str 
        .Split(';') 
        .Select(i => { item++; return int.Parse(i); }) 
        .ToArray(); 
      }) 
      .ToList(); 
    } 
    catch 
    { 
     throw new FormatException($"Wrong line [{line}]; item [{item}]"); 
    } 
} 

デモ:https://dotnetfiddle.net/uGtw7A

+0

Thx、それは私に助けになった! – Alexandr

0

スコープはスコープです。 tryブロック内で定義したもので、明示的に渡されないものは、あなたのcatchブロックでは利用できません。あなたがリストの上に手動で反復処理し、個々の試みをキャッチしようとする必要があり、この情報が必要な場合は

...

1

あなたは例外を発生させたオブジェクトへの参照が必要です。しかし、インスタンスがtryブロックの範囲内にしか存在しないため、参照を宣言しない限り、それ以上アクセスすることはできません(同じスコープを共有することはできず、同じ変数にアクセスできません)あなたは、単に、すべてのこれらの例外を回避することができますしかし

public static List<int[]> Parse(List<string> list) 
{ 
    var result = new List<int[]>(); 
    foreach(var str in list) 
    { 
     try 
     { 
      var values = str.Split(';'); 
      result.Add(Tuple.Create(
         int.Parse(values[0]), 
         int.Parse(values[1]), 
         int.Parse(values[2])) 
        ); 
     } 
     catch 
     { 
      //here in braces I want to know, which element was wrong 
      throw new FormatException($"Wrong line " + str"); 
     } 
    } 
    return result; 
} 

:すでにあなたは現在の行へのアクセス権を持っているために、通常のforeach -loopを使用する必要がありますコメントで述べたのtry-圏

として外部にそのインスタンスへ代わりにTryParseを使用し、解析に失敗した場合はfalseを返します。これは、このようなものに沸く:

var values = str.Split(';'); 
int v0, v1, v2; 
if(int.TryParse(values[0], out v0 && 
     int.TryParse(values[1], out v1 && 
     int.TryParse(values[2], out v2 &&)) 
    result.Add(Tuple.Create(v0, v1, v2)); 
else 
    throw new FormatException($"Wrong line " + str"); 
0

あなたのコードと、あまりにも多くの問題がありますが、あなたはそのパラメータlistがnullでなく、3つの文字列に分割さできる項目が含まれており、すべての文字列と仮定しています安全に、intに解析できます。私は手動で十分な要素を持ってチェックし、その後、数にTryParseを使用して、データを分割し、をループをお勧めします

public static List<int[]> Parse(List<string> list) 
{ 
    if (list == null) 
    { 
     throw new ArgumentNullException(nameof(list)); 
    } 

    var arrayOfStringArray = list 
     .Select(x => x.Split(';')) 
     .ToArray(); 
    var resultList = new List<int[]>(); 

    for (var i = 0; i < arrayOfStringArray.Length; i++) 
    { 
     var arrayOfString = arrayOfStringArray[i]; 

     if (arrayOfString.Length != 3) 
     { 
      throw new InvalidOperationException("meaningfull message there!"); 
     } 

     var arrayOfInt = new int[3]; 

     for (var j = 0; j < arrayOfInt.Length; j++) 
     { 
      arrayOfInt[j] = TryParse(arrayOfString[j], i, j); 
     } 

     resultList.Add(arrayOfInt); 
    } 

    return resultList; 
} 

static int TryParse(string value, int line, int position) 
{ 
    int result; 

    if (!int.TryParse(value, out result)) 
    { 
     throw new FormatException($"Item at position {line},{position} is invalid."); 
    } 

    return result; 
} 
+0

これは私の本当のコードではありません、それはちょうど短い例です。 – Alexandr

1

:あなたは上記のすべての保証をしていない場合は、単にすべてをチェック

。私はこれがLINQのを使用してからの出発である知っているが、それはエラーチェックでこれを行うには良い方法だ:

public static List<int[]> Parse(List<string> list) 
{ 
    if (list == null) 
    { 
     throw new ArgumentNullException("list"); 
     // you can use nameof(list) instead of "list" in newer versions of C# 
    } 

    List<int[]> result = new List<int[]>(); 
    // Loop through the entries 
    for (int i = 0; i < list.Count; ++i) 
    { 
     // Be safe and check we don't have a null value 
     // I'm just skipping the 'bad' entries for now but 
     // you can throw an error, etc. 
     if (list[i] == null) 
     { 
      // do something about this? (an exception of your choosing, etc.) 
      continue; 
     } 

     // split the entry 
     string[] entryData = list[i].Split(';'); 
     // check we have 3 items 
     if (entryData.Length != 3) 
     { 
      // do something about this? 
      continue; 
     } 

     // try to parse each item in turn 
     int a; 
     int b; 
     int c; 

     if (!int.TryParse(entryData[0], out a)) 
     { 
      // do something about this? 
      continue; 
     } 

     if (!int.TryParse(entryData[1], out b)) 
     { 
      // do something about this? 
      continue; 
     } 

     if (!int.TryParse(entryData[2], out c)) 
     { 
      // do something about this? 
      continue; 
     } 

     // add to the results list 
     result.Add(new int[] { a, b, c }); 
    } 

    // return the result 
    return result; 
} 
0

は、私はあなたがちょうどここに間違ったアプローチだと思います。はい、Tuple + Linqを使用するのは結果を得るための最も怠惰な方法ですが、カスタムエラーを生成することはできません。

static void Main(string[] args) 
    { 
     var result = Parse(new List<string>() { "3;5;7", "qwe;3;70" }); 
    } 

    public static List<Tuple<int, int, int>> Parse(List<string> list) 
    { 
     List<Tuple<int, int, int>> result = new List<Tuple<int, int, int>>(); 
     int line = 0; 
     int errorCol = 0; 

     try 
     { 
      for (line = 0; line < list.Count; line++) 
      { 
       string[] curentLine = list[line].Split(';'); 
       int result0, result1, result2; 
       errorCol = 1; 

       if (curentLine.Length > 0 && int.TryParse(curentLine[0], out result0)) 
        errorCol = 2; 
       else 
        throw new Exception(); 

       if (curentLine.Length > 1 && int.TryParse(curentLine[1], out result1)) 
        errorCol = 3; 
       else 
        throw new Exception(); 

       if (curentLine.Length > 2 && int.TryParse(curentLine[2], out result2)) 
        result.Add(new Tuple<int, int, int>(result0, result1, result2)); 
       else 
        throw new Exception(); 
      } 

      return result; 
     } 
     catch 
     { 
      //here in braces I want to know, which element was wrong 
      throw new FormatException("Wrong line " + line + " col" + errorCol); 
     } 
    } 

PS:ここでは0で、ラインと列の開始をここで

は、あなたが似て何かを達成することができます方法の例です。

関連する問題