C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.41377 の関連記事表示

<< 0 >>
■41377  Re[5]: C#における値渡しと参照渡しのコーディングについて
□投稿者/ 魔界の仮面弁士 -(2009/09/18(Fri) 16:38:39)
    2009/09/18(Fri) 17:54:07 編集(投稿者)

    No41366 (simano さん) に返信
    > ですが、「参照渡しを行いたい需要もある」、

    引数の型が値型であるか参照型であるかに関わらず、
    引数に参照渡しを必要とする場合というのは通常、
    No41329 のパターンにほぼ限られるかと思います。

    それ以外のパターンだと、P/Invoke の場合ぐらいでしょうか。


    > 例えば、サーバと通信して、「実データ」と「結果値」を受ける仕様になっているとします。
    > 「結果値」が「クライアントから受けた値が不正です」だった場合の処理を書いてみました。
    > (…略…)
    > 上記の場合、(…略…)例外のパターンを把握するのも一苦労だと思います。
    例外が嫌なら、「他の方法で通知する」か「失敗の理由は通知しない」のいずれかかと。

    GetFromServer メソッドの利用側に、どのような記述を行わせるのであれば、
    「一苦労しない」方法になると思いますか?

    ---------------
     // 出力引数
     ResultStatus status;
     MyData result = obj.GetFromServer(0, out status);
     if(status == ResultStatus.InvalidData) {
      MessageBox.Show("失敗1");
      return;
     }
    ---------------
     // 戻り値(値型)での判定
     MyData resultStruct = obj.GetFromServer(0);
     if(resultStruct.HasError) {
      MessageBox.Show("失敗");
      return;
     }
    ---------------
     // 戻り値(参照型)での判定
     MyData resultClass = obj.GetFromServer(0);
     if(resultClass == null ) {
      MessageBox.Show("失敗");
      return;
     }
    ---------------
     // エラープロパティでの判定
     MyData result = obj.GetFromServer(0);
     if(obj.LastDllError != Win32Error.NO_ERROR ) {
      MessageBox.Show("失敗:" + obj.LastDllError);
      return;
     }
    ---------------
     // エラー通知イベントでの捕捉
     obj.OnError += delegate { MessageBox.Show("失敗"); }; // エラー理由はイベント引数で
     MyData result = obj.GetFromServer(0);
    ---------------
     // 例外処理
     MyData result;
     try {
      result = obj.GetFromServer(0);
     } catch(……) {
      if(!Recovery(〜)) throw;
     } catch(……) {
      MessageBox.Show("失敗");
      return;
     }
    ---------------

    # 他にも幾つかのパターンが考えられるかと思います。


    > 「結果値」が「クライアントから受けた値が不正です」だった場合の処理を書いてみました。
    結局、最後まで MyData が return される事が無いので、そもそもこのままだと
    コンパイルエラーになってしまうかと思いますが、それはさておき。


    > catch (Exception e)
    > {
    > throw;
    > }
    この catch 句は無意味だと思いますが……この場合の try/catch は、
    どのような動作を目的として記述されているのでしょうか?


    > MyData data = new MyData();
    > data = Server_DataBytes_Value; // サーバの返した実データを渡す。
    この記述からして、Server_DataBytes_Value とは、
    MyData 型のフィールド変数のようですね。

    この場合、最初に割り当てたインスタンスが意味をなしていません。
    単純に「MyData data = Server_DataBytes_Value;」で良いかと。


    > int val = Server_Return_Value; // サーバの返した結果値を渡す。
    > if (val == ILLEGAL_ARG) // 「クライアントから受けた値が不正です」などのエラー値。
    > {
    > throw new MyServerException(val); // 自作の例外クラス
    > }
    上記の Server_Return_Value は、int 型のフィールド変数ですかね。
    比較対象の ILLEGAL_ARG は…… int 型の定数でしょうか?

    ここで、変数名を一旦 val に受け直している意図は分かりませんが
    (変数名が分かりにくくなっただけのような…?)、何にせよ、
    この『GetFromServer メソッド』というものは、
    「サーバーと通信して MyData を返す。返せないときは例外を発生。」
    という目的で実装されたメソッドという事になるかと思います。

    で、その例外のひとつに、「new MyServerException(ILLEGAL_ARG)」がある、と。


    > そこで、「結果値」は、戻り値として返す処理が適切なのかなと思いました。
    例外だと把握しきれなくて、ILLEGAL_ARG などのint 型(を戻り値や出力引数)で
    返す場合には把握することができる…という事にはならないかと。


    > dllだったら例外のパターンを把握するのも一苦労だと思います。
    それは例外に限らず、どのような返し方であっても一緒では無いでしょうか。

    戻り値にしろ、出力引数にしろ、例外にしろ、それらに変更があったのであれば、
    利用側にも修正が必要になるでしょうし、利用側に影響を与えたくないのであれば、
    内部実装は変更しても、出力情報に対しては手を加えないようにするべきかと思います。


    > 後でいつのまにか例外の種類が変わってたらcatchできません。
    「例外の種類を変える」とは、どういう意味でしょうか?

    ・ILLEGAL_ARG の意味が変わったので、利用側が MyServerException.val を利用できなくなった。
    ・MyServerException の例外が、サーバーエラー以外に対しても throw されるようになった。
    ・MyServerException を廃止して、別の例外が throw されるように実装し直した。
    ・MyServerException だけでなく、他の新たな例外も throw される可能性が出てきた。
    ・素の MyServerException でなく、その継承クラスを throw させることになった。
記事No.41320 のレス /過去ログ71より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -