DOBON.NETプログラミング道掲示板
(現在 過去ログ3 を表示中)

[ 最新記事及び返信フォームをトピックトップへ ]

■34133 / inTopicNo.1)  例外発生した場合に変数をcatchに渡したい
  
□投稿者/ ssd 一般人(1回)-(2019/02/15(Fri) 10:55:29)
  • アイコン環境/言語:[c# .net4.5] 
    分類:[.NET] 

    DataTable dt = new DataTable();
    try
    {
    foreach (DataRow dr in dt.Rows)
    {
    int iHogeOld = (int)dr["HOGE"];
    }
    }catch(Exception e)
    {
    //ここでdr["HOGE"]の値を表示したい
    }

    foreach内で型変換に失敗した場合、catch側で何が失敗したのか知りたいです。
    この場合、catchの方に変数の値を渡したいのですが、どうすればいいでしょうか?
引用返信 削除キー/
■34134 / inTopicNo.2)  Re[1]: 例外発生した場合に変数をcatchに渡したい
□投稿者/ ひできち 一般人(1回)-(2019/02/15(Fri) 11:25:09)
  • アイコンDataTable dt = new DataTable();
    DataRow dr;

    try
    {
    foreach (dr in dt.Rows)
    {
    int iHogeOld = (int)dr["HOGE"];
    }
    }catch(Exception e)
    {
    debug,write(dr["HOGE"]);
    }


    でいいのは?
引用返信 削除キー/
■34135 / inTopicNo.3)  Re[2]: 例外発生した場合に変数をcatchに渡したい
□投稿者/ ssd 一般人(2回)-(2019/02/15(Fri) 13:25:51)
  • アイコンforeach文の構文を確認してみると、下記のようになっています。

    foreach(型名 変数 in コレクション)


    実際に試してみると、dtは変数ですが、種類のように使用されていますと表示されます。
引用返信 削除キー/
■34136 / inTopicNo.4)  Re[1]: 例外発生した場合に変数をcatchに渡したい
□投稿者/ まりもん 一般人(6回)-(2019/02/15(Fri) 14:23:04)
  • アイコン
    DataTable dt = new DataTable();
    try
    {
        foreach (DataRow dr in dt.Rows)
        {
            try
            {
                int iHogeOld = (int)dr["HOGE"];
            }
            catch(Exception e)
            {
                //ここで出力
                Console.WriteLine(dr["HOGE"]);
                Throw;
            }
        }
    }catch(Exception e)
    {
        //既存の例外処理
    }
    
    こういうのはどうでしょう?

引用返信 削除キー/
■34137 / inTopicNo.5)  Re[3]: 例外発生した場合に変数をcatchに渡したい
□投稿者/ ひできち 一般人(2回)-(2019/02/15(Fri) 17:05:50)
  • アイコンNo34135に返信(ssdさんの記事)
    > foreach文の構文を確認してみると、下記のようになっています。
    >
    > foreach(型名 変数 in コレクション)
    > 文
    >
    > 実際に試してみると、dtは変数ですが、種類のように使用されていますと表示されます。

    いやーごめんなさい。適当な回答をしてしまいまして、申し訳なかったです

    局所的にcatch する方針でガリガリ書いてしまうのは
    あまりスマートとは言えないので、そうではなく実装したい場合は
    以下のようになりますね

    DataTable dt = new DataTable();
    DataRow dr = null;
    try
    {
    for (int i = 0; i < dt.Rows.Count; i++)
    {
    dr = dt.Rows[i];
    int iHogeOld = (int)dr["HOGE"];
    }
    }
    catch (Exception e)
    {
    //ここでdr["HOGE"]の値を表示したい
    Console.WriteLine(dr["HOGE"]);
    }


引用返信 削除キー/
■34138 / inTopicNo.6)  Re[1]: 例外発生した場合に変数をcatchに渡したい
□投稿者/ 魔界の仮面弁士 大御所(1196回)-(2019/02/15(Fri) 17:51:45)
  • アイコン2019/02/15(Fri) 18:59:22 編集(投稿者)

    No34133に返信(ssdさんの記事)
    > DataTable dt = new DataTable();
    > try
    > {
    >  foreach (DataRow dr in dt.Rows)
    >  {

    行数が 0 なのでそもそもループ処理に入らないですが、
    それは本題ではないので置いといて…。



    > catch(Exception e)

    そもそも論で言えば、すべての例外を無条件に拾うことは望ましくありません。

    実行時例外で処理するしかない処理(通信エラー等)以外は捕らえるべきではないので、
    「int に変換できないような値が DataTable に混入しないようにする」か、
    「int に変換できる場合にのみキャストする」などして、
    例外を発生しないコードに書き換えることも検討してみてください。


    例外処理のための参考資料を紹介しておきます。
    https://blogs.msdn.microsoft.com/nakama/2008/12/29/net-part-1/
    https://blogs.msdn.microsoft.com/nakama/2009/01/02/net-part-2/
    https://blogs.msdn.microsoft.com/nakama/2009/01/18/net-part-3/
    https://blogs.msdn.microsoft.com/nakama/2009/01/23/net-part-4/
    https://blogs.msdn.microsoft.com/nakama/2009/01/08/netjava/


    >   int iHogeOld = (int)dr["HOGE"];

    ということで、例外が発生しないようにする方法の一つとして、
     // int 以外は(DBNull など)は -999 として取り扱う
     int intHoge = dr["HOGE"] as int? ?? -9999;
    のようにするという手もあろうかと思います。



    > foreach内で型変換に失敗した場合、catch側で何が失敗したのか知りたいです。

    何らかの理由で、catch で捕らえる必要があるのだとしても、
    例外処理として「型変換」のみを取り扱いたいのであれば、
    【Exception】ではなく【InvalidCastException】を捕らえるべきかと思います。


    foreach (DataRow dr in dt.Rows)
    {
     // object[] rawData = dr.ItemArray; // 全部の列の値をまとめて取得
     object rawHoge = dr["HOGE"]; // 特定の列の値のみ取得
     try
     {
      int iHoge = (int)rawHoge; // int 型に unbox
     }
     catch (InvalidCastException)
     {
      Console.WriteLine("HOGE 列の値「{0}」を int に変換できませんでした。(型名:{1})", rawHoge, rawHoge.GetType().FullName);
      // throw;
     }
    }



    >   int iHogeOld = (int)dr["HOGE"];

    実際の値が DBNull や long であった場合、上記の処理は確かに失敗しますが、
    ここで発生しうる例外は、unbox の失敗によるものだけではないはずです。


    たとえば列名が間違っていれば、引数例外の【ArgumentException】が起きることもありますし、
    削除済み行にアクセスしようとして【DeletedRowInaccessibleException】となることもあるわけで。
引用返信 削除キー/
■34139 / inTopicNo.7)  Re[2]: 例外発生した場合に変数をcatchに渡したい
□投稿者/ ssd 一般人(3回)-(2019/02/15(Fri) 18:04:37)
  • アイコン
    まりもんさん
    
    catch(Exception e)
     {
      //ここで出力
        Console.WriteLine(dr["HOGE"]);
        Throw;
    }
    
    の箇所でConsole.WriteLine(dr["HOGE"]);は出力できないような気がします。
    試してみましたがはやり駄目でした。
    
    ご回答ありがとうございます。

引用返信 削除キー/
■34140 / inTopicNo.8)  Re[2]: 例外発生した場合に変数をcatchに渡したい
□投稿者/ ssd 一般人(4回)-(2019/02/15(Fri) 18:06:47)
  • アイコンひできちさん

    foreachではなく、forでやるのですか。
    なるほど、なるほど。何か良い気がします。ありがとうございます。
引用返信 削除キー/
■34141 / inTopicNo.9)  Re[3]: 例外発生した場合に変数をcatchに渡したい
□投稿者/ タイガー 一般人(1回)-(2019/02/18(Mon) 14:40:25)
  • アイコン
    > catch(Exception e)
    > {
    >   //ここで出力
    > Console.WriteLine(dr["HOGE"]);
    > Throw;
    > }
    >
    > の箇所でConsole.WriteLine(dr["HOGE"]);は出力できないような気がします。
    > 試してみましたがはやり駄目でした。

    もりまんさんのコードはtry〜catchの2段重ねで、上記は内側のcatchのため、dr["HOGE"]は表示できますよ。

引用返信 削除キー/
■34142 / inTopicNo.10)  Re[3]: 例外発生した場合に変数をcatchに渡したい
□投稿者/ ssd 一般人(5回)-(2019/02/19(Tue) 09:39:13)
  • アイコンみなさま、ありがとうございます。

    例外に対する考えが甘かったです。反省。

    もりまんさん。申し訳なかったです、実行できました。

    ありがとうございました!
解決み!
引用返信 削除キー/



トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

Mode/  Pass/


- Child Tree -