2017-08-27 6 views
0

私は3つのパラメータ(日、月&年)をとり、新しいdateTimeを作成する関数を持っています。 3つのコンボボックスのいずれかがドロップダウンされたときに呼び出されるpublic関数です。例外が発生しない場合は例外をスローして処理する必要がありますか?

私が誤って無効な値を入力したときに無効な日付時間例外がスローされましたが、コンボボックスに有効な値があらかじめ設定されているため、アプリケーションではこれを実行できません。

私はまだ関数内でこの例外をチェックして処理する必要がありますか?

+1

のよく知られたパターンに従うことは比較的容易です。 – Steve

+0

私は何かを理解していません あなたが言った**ユニットテスト時に私は間違って無効な値を入力しました** **コンボボックスに有効な値のみ**があらかじめ設定されていると、 – Youssef13

+0

それは私が心配しているものです!ちょうどベストプラクティスが不思議ですが、不必要にメソッドをオーバーコンプリートしていないのでしょうか? – user5467760

答えて

2

一般的には、あらゆる公共の関数をどこからでも呼び出すことができます。また、ある時点で無効な入力からコードを守ることをお勧めしますあなたは、誰が関数への入力をフィードしているか確信しています。

しかし、この想定された関数は、入力がうまくいかないと例外をトリガーすることなく、不可能な状況を単独で処理できます。

入力をチェックして、私はあまりにも多くの_impossible situation_が起こる見てきましたTryParse

public bool TryMakeDateTime(int year, int month, int day, out DateTime date) 
{ 
     date = DateTime.MinValue; 

     if(!IsValidDay(year, month, day)) 
     return false; 

     date = new DateTime(year, month, day); 
     return true; 
} 

public bool IsValidDay(int year, int month, int day) 
{ 
    if(day < 1 || day > 31) 
     return false; 

    if(month < 1 || month > 12) 
     return false; 

    if(day > 30 && (month == 2 || 
        month == 4 || 
        month == 6 || 
        month == 9 || 
        month == 11)) 
     return false; 

    // This is arbitrary, adjust the check to your constraints 
    if(year < 1900 || year > 2099) 
     return false; 

    if(month == 2) 
    { 
     // IsLeapYear cannot handle values below 1 or higher than 9999 
     // but we have already checked the year with more retrictive 
     // constraints. 
     int extraDay = (DateTime.IsLeapYear(year) ? 1 : 0); 
     if(day > (28 + extraDay)) 
      return false; 
    } 
    return true; 
} 
+0

申し訳ありませんが、今では、オンザフライで書かれたコードをテストするためのPCを用意しており、このコードの最初のバージョンでいくつかの問題を修正しました。 – Steve

0

例外を防ぐか、キャッチしないでください。しかし、 "不可能な"ケースで例外が実際に起こることを確認する必要があります。

例外は、「通常」発生しないと考えられる「不可能な」状態を意味します。

たとえば、DateTimeコンストラクタのオーバーロードを呼び出すと、入力が無効な場合、そのコンストラクタはすでに例外をスローします。あなたの状況では起こらないと思うなら、その事件は処理しないでください。フレームワークによって生成された例外メッセージは正常です。

1

はい、無効な入力を無効にする必要があります。機能では、無効な入力を送信することができます。将来の開発者がこの関数をどのように、あるいはどこから呼び出すのかはわかりません。しかし、有効な入力のみが許可されるように関数をコーディングする方が良い方法もあります。

入力の種類を整数値から列挙型に変更することでこれを行うことができます。あなたが来月の最初として、それらにわずか30日間で数ヶ月の31日を治療するための機能をコーディングし、2月29日でした月のEnum

public enum CalendarMonth { 
    NotSet = 0, January = 1, February = 2, 
    March = 3, April = 4, May = 5, June = 6, 
    July = 7, August = 8, September = 9, 
    October = 10, November = 11, December = 12} 

とDAYOFMONTH列挙

public enum DayOfMonth { 
    NotSet = 0, dom1 = 1, dom2 = 2, ....etc., ... dom31 = 31 } 

を作成します。 、30および31を3月1,2,3などとして無効に扱うことは避けてください。関数の署名は

public DateTime NewDate(DayOfMonth dom, CalendarMonth month, int year); 

となり、無効な値を渡すことはできません。 (DateIme.MinDateからDateTime.MaxDateの範囲外の年の値を除いて)

関連する問題