2009-07-09 9 views
1

私は単純な小さなクラスをコーディングしています。私の目標は、従来のVisual Basic 6プロジェクトでそれを実装し、それをCOM相互運用機能を介してCOMオブジェクトとして公開することです。例外処理:引数の検証にはどの程度細かいことがありますか?

解決方法がわかりにくい、パラメータを検証するにはどの程度細かいことが必要かということがわかります。そう、どれ提案はあまり理解されるであろう

public class MyMailerClass 
{ 
    #region Creation 
    public void SendMail(string from, string subject, string to, string body) 
    { 
     if (this.IsValidMessage(from, subject, to, body)) // CS1501 
     { 
      MailMessage msg = new MailMessage(); 
      msg.IsBodyHtml = true; 
      msg.From = new MailAddress(from); 
      msg.To.Add(to); 
      msg.Subject = subject; 
      msg.Body = body; 
      SmtpClient srv = new SmtpClient("SOME-SMTP-HOST.COM"); 
      srv.Send(msg); 
     } 
     else 
     { 
      throw new ApplicationException("Invalid message format."); 
     } 
    } 
    #endregion Creation 

    #region Validation 
    private bool IsValidMessage(string from, string subject, string to, string body) 
    { 
     Regex chk = new Regex(@"(\[email protected][a-zA-Z_]+?\.[a-zA-Z]{2,6})"); 
     if (!chk.IsMatch(from)) 
     { 
      return false; 
     } 
     if (!chk.IsMatch(to)) 
     { 
      return false; 
     } 
     if (!string.IsNullOrEmpty(subject)) 
     { 
      return false; 
     } 
     if (!string.IsNullOrEmpty(body)) 
     { 
      return false; 
     } 
     else 
     { 
      return true; 
     } 
    } 
    #endregion Validation 
} 

:その光に、私は本当に程度満足していない、との事は、全く私は実際に例外を処理しています方法の詳細さではありませんご参考までにすべてに感謝します!

注::エンタープライズライブラリのValidation Application Blockをこの特定のケースで実装すると便利でしょうか?

+0

あなたは、サイドノートとしてここ

はあなたが役に立つかもしれません私はこのテーマに書いた記事のカップルですArgumentExceptionを使用していますwrong - 2番目の引数は_string_で、無効な引数の_name_でなければなりません。代わりに、引数の値を渡しています。 '新しいArgumentExceptionがスロー:あなたが何かを行う必要があります(「無効な送信者アドレスを:」+から、「から」);' –

+0

おかげで多くのパベルが、私はそれを追加しています! –

+0

新しいバージョンのコードはデバッグが難しいでしょう。 IsValidMessage()では、すべての条件を1行でチェックします。デバッガを使用してコードをステップ実行するときに、どのコードが満足できないのかをどのようにして知ることができますか?次のように書くことはできません:if(string.IsNullOrEmpty(subject)){return false; } if(!string.IsNullOrEmpty(body)){戻り値はfalseです。 } Regexオブジェクトを作成して、条件を一度にチェックして、条件が満たされなくなったらすぐにfalseを返します。 – sharptooth

答えて

9

あなたがSendMailの発信者に課している契約を考えてみましょう。彼らはあなたに "有効な電子メールアドレス"を渡す必要があります。有効なものは誰が決定しますか? SendMailは行います。基本的にあなたの方法は「高いメンテナンス」です。それは、物事を正確に望みます。あなたが与えるものが満足できるものであるかどうかを判断する唯一の方法は、ベストを尽くすことです。

呼び出し元に満足度を知らせる機会を与えずに、または少なくとも例外を回避する手段を持たずに、高度な保守方法を記述しないでください。ブール値を返す "IsValidAddress"メソッドに検証ロジックを抽出します。次に、SendMailメソッドがIsValidAddressを呼び出して、無効な場合はスローします。懸念の

(1)増加の分離:

は、この変更のいくつかの素敵な効果を得ることができます。 SendMailの仕事は、電子メールメカニズムが機能するようにし、電子メールアドレスが有効かどうかの判断に合格しないことです。そのポリシーの決定を検証に特化したコードに分離します。

(2)アドレス検証自体のに有用なツールです。アドレスがメールを送信せずに整形式であるかどうかを知りたい場合は、多くの場合があります。それはすべて1つの賢明な場所にあるので、

(3)あなたが簡単に検証ロジックを更新し、向上させることができます。

(4)発信者は、彼らは例外がスローされないことを保証できるような方法があります。呼び出し元が引数が有効であることを保証せずにメソッドを呼び出すことができない場合は、例外を捕捉する必要があります。理想的には、コードを正しくするために呼び出し元に例外を処理させる必要はありません。たとえ手渡されたデータが悪い場合であっても、投げられない正しいコードを書く方法があるはずです。

例外処理:http://ericlippert.com/2008/09/10/vexing-exceptions/

高メンテナンス方法:http://blogs.msdn.com/ericlippert/archive/2008/09/08/high-maintenance.aspx

+0

エリックは、私は精緻な固体アドバイスをあなたに多くのことを感謝したいと思います! –

3

2つのthrowステートメントを連続して実行すると、最初のものだけが実行され、制御が例外ハンドラに渡され、2番目のthrowには決して渡されません。

私の意見では、「送信者の電子メールは無効です」というような単純なことだけで十分です。電子メールは非常に単純で短く、ユーザーは追加のガイダンスなしでこれを解決することができます。

また、渡された値をすべて確認してから作業を開始する方が良いと思います。無効なパラメータ値に遭遇して例外をスローし、この作業を完了できない場合には、部分的に作業を行うという点は何ですか?可能であれば、できるだけ早い段階でエラーを表示してください。

+0

は、だから、ソートの最後に「isMsgOk =真」の形で、多分ブールフラグを運ぶ、方法の最初に、おそらく三の方法で、すべてのパラメータの有効性をチェックし、すべての作曲をしているように意味しますそこ? –

+0

いいえ、例外があるときにフラグを使用するのはなぜですか?各パラメータをチェックすることができます。最初に無効な値が見つかったら例外をスローします。 – sharptooth

1

そして:

使用

string.IsNullOrEmpty(subject) 

ではなく、あなたの文字列が空であるかどうかをチェックするための

subject == null 

+0

Jasonのスニペットをありがとう!私はそれを含めています。 –

関連する問題