2011-10-11 13 views
6

私はシリアルポート経由で通信する制御回路を持っています。応答コマンドが特定の形式と一致しない場合、私はそれをエラーとみなし、エラーコードを返すべきか、例外をスローするべきか疑問に思っていましたか?例:C#エラーコード対例外

public double GetSensorValue(int sensorNumber) 
{ 
    ... 
    string circuitCommand = "GSV,01," + sensorNumber.ToString(); // Get measurement command for specified sensor. 
    string responseCommand; 
    string expectedResponseCommand = "GSV,01,1,OK"; 
    string errorResponseCommand = "ER,GSV,01,1,62"; 

    responseCommand = SendReceive(circuitCommand); // Send command to circuit and get response. 

    if(responseCommand != expectedResponseCommand) // Some type of error... 
    { 
     if(responseCommand == errorResponseCommand) // The circuit reported an error... 
     { 
     ... // How should I handle this? Return an error code (e.g. -99999) or thrown an exception? 
     } 
     else // Some unknown error occurred... 
     { 
     ... // Same question as above "if". 
     } 
    } 
    else // Everything is OK, proceed as normal. 
     ... 
} 

ありがとう!

答えて

8

ほとんどすべてケース例外を介してエラーを伝えます。私はほとんど "エラーコード"を使用することはほとんどありません。時折、成功/失敗を結果としてint.TryParseなどで与えるのは便利ですが、このような状況はそれほどうまくいかないと思います。これは実際のエラー状態のように聞こえて、それ以上の進歩を止めるべきなので、例外が適切です。

EDIT:コメントに記載されているように、エラーを報告している回線が実際に「期待」で、呼び出し元がそれに対処でき、その状況を積極的に探している場合は、ステータスコードを使用するのが妥当です。

残念ながらエラー処理...私たちは本当に正しいまだソフトウェア工学では持っていないものの一つである

+0

興味深いでてくる可能性があっても、取り扱いが容易です。私は標準的なエラー処理の例外を推奨することに驚いています。珍しいまたは予期せぬ状況の例外を予約しませんか? –

+0

@JohnWeldon:いいえ、私はエラーのために呼び出しコードがすべてが大丈夫だったかのように進んではならないことを意味します。 "*応答コマンドが特定の形式と一致しない場合、私はそれをエラーとみなします。" –

+0

プログラムの通常の流れはこのケースを扱うことを意図していませんか?私はその場合の例外の使用に同意します。しかし、プログラムが通常このエラー状態に応答すると予想される場合、私は例外を使用しません。質問の私の解釈は後者でしたが、前者は同じように妥当であろう。 –

2

あなたの場合は例外をスローする方が良いです。このメソッドの呼び出し側は、「正当な」出力とエラー状態を区別することができるからです。エラーコードを返すと、それは依然として数値であるため、呼び出し元はコントロール回路からの出力として誤った解釈をする可能性があります。

3

厳密にあなたは「例外的」な状況にいるときに例外が使用されるに言えば、すなわちあなたが期待していないもの。

それが私だったら、私はおそらく最初のケース(既知のエラー応答)にエラーコードを返し、第2のケース(不明なエラーコード)で例外をスローしたい個人的に

+0

+1保険会社がしなかったことを後で見つけ出すために運転規則を尊重しない人に私が(=例外を投げて)運転することを許しているのと同じように、必要なもの(例外を処理する)。 – Arun

2

、私が対処したいです何らかの種類のレスポンスオブジェクトを定義することで、このような状況になります。私はこれを経験して、例外的とみなされるべきものを計量することによってこれに着きました。あなたが何らかのデバイスと接続していて、ユーザーがデバイスをオフにしたり、何かをオフにしている場合、これは例外的な状態です。例外がスローされます。

デバイスへの特定のメソッド呼び出しが失敗した場合など、これは例外ではありませんが、エラーです。私はダブルを返す場合、私は魔法の数字を定義したくないし、例外をスローしたくない。だから、私は次のようなものを定義します:

class DeviceResult //could also be struct 
{ 
    public double ReturnValue { get; set; } 
    public bool IsValid { get; set; } 
    public string ErrorMessage { get; set; } 
} 

ここでの詳細はあまり重要ではありません。この例では、クライアントAPIは有効かどうかをチェックし、有効な場合は戻り値を使用します。マジック番号も例外もありません。そのパラダイムはより重要なことです。私はそれを見て、あなたはオブジェクト指向言語を使用しているので、オブジェクトを使うこともできます。 :)

+0

ちなみに、デバイスAPIからの戻り値の型が複数ある場合は、DeviceResult を返す値を "T"に設定して、 –

0

エラーコード。

  1. 例外をスローすると値が返されるよりも遅くなります。
  2. メソッドのシグネチャを自由に設計できるため、必要なタイプを返す可能性があります。意味のある方法で拡張できない特定の型を返さなければならない場合は、間違いなく例外をスローする必要があります。
  3. メソッドを呼び出すときに、エラーコードよりも例外を見逃しやすいです。あなたのメソッドが投げている例外を文書化し、他の開発者がそれを読むことを願ってください。
  4. GetSensorValueメソッドの応答には異なるパスがあります。 「幸せな道」は明らかに予想され、最も興味深いものです。しかし、コンシューマーがhapyパスの少ない結果を処理できることが分かっている場合は、「不幸なパス」の応答がより期待されるため、エラーコードを表示することは理にかなっています。
  5. 多くの例外をスローすると、デバッガの例外設定に応じてデバッガが絶えず動作する可能性があります。
  6. エラーコードを返すと、応答タイプがより複雑になり、値をアンラップするコードがさらに必要になります。しかし、try-catchの代わりに "if(response.Status == Statuses.Success){var value = response.Value;}"を読み書きすることは本当に難しいですか?

それが例外をスローすることをお勧めです:あなたはあなたのメソッド呼び出しが失敗することを予見できた場合(あなたがそれを実行する前に、操作を実行できるかどうかをチェック)

  1. が。 "perform"メソッドを実装してエラーコードを返すこともできますが、このチェック実行メソッドのペアはパターンと見なされます。
  2. レスポンスタイプを意味のある方法で拡張することはできませんが、メソッドのコントラクトで予期していない状態でレスポンスを通知する必要があります。
  3. 前と同じように、「幸せなパス」の結果だけを返すのがよい理由があります。
0

私が原因いくつかの単純な事実にほとんどのケースで例外を使用することをお勧めします:

  1. 例外はグローバルで、すべてのC#の-developersは、デバッグのためにそれを使用する方法(できればと)例外が何であるかを知っています。
  2. 例外は、すべての呼び出しメソッドから最も近い "try catch"に分割されます。 複数のレイヤーがあり、最内層が例外をスローすると、そのレイヤーが望むレイヤー(通常は最外層または最外層)でその例外を処理できます。
  3. ほとんどのプロジェクトタイプには、単純なグローバル例外処理コードを実装するためにオーバーライド/サブスクライブできるオーバーライド可能なメソッドまたはイベントがあります。これにより、エラーメッセージの書式設定、ロギングの実行、メールの送信、神への祈り(例外を処理するときにあなたがやっていること)を簡単に行うことができます。

    1. それが例外をスローするように自由ではありません:

    は、しかし、考慮すべきいくつかのことがあります。あなたのコードを100%最適化する必要がある場合、例外を投げることは避けたいことかもしれません。

  4. 例外には、必要のない情報がたくさんあります。単純にエラーメッセージを表示するだけの場合は、本当にスタックトレースが必要ですか?

しかし、一般的なルールとして、私が言うと思います:例外に固執する、それが簡単で、有益、デバッグ、それはわずかなパフォーマンスコスト