8

私は MSDN を掘り下げていて、興味深いアドバイスが 1 つあるこの記事を見つけました。いくつかのオプションに基づいて、例外をスローまたはスローしないパブリック メンバーを持たないでください。

例えば:

Uri ParseUri(string uriValue, bool throwOnError)

もちろん、これは 99% のケースで恐ろしいことであることがわかりますが、時折使用することは正当化されるでしょうか?

データベースまたは構成ファイル内のデータにアクセスするときに、「AllowEmpty」パラメーターを使用して使用されているのを見たことがあります。例えば:

object LoadConfigSetting(string key, bool allowEmpty);

この場合、代替手段は null を返すことです。ただし、呼び出し元のコードには、null 参照チェックが散らばっています。(また、このメソッドでは、特に設定可能な値として null を実際に許可する機能も排除されます)。

あなたの考えは何ですか?なぜこれが大きな問題になるのでしょうか?

4

8 に答える 8

10

ブール値に基づいてスロー/ノースローの決定を行うことは間違いなく悪い考えだと思います。つまり、ブール値の意味を判断するために、コードの一部を見る開発者がAPIの機能的な知識を持っている必要があるためです。これ自体は悪いことですが、根本的なエラー処理を変更すると、開発者がコードを読んでいるときに間違いを犯しやすくなる可能性があります。

この場合、2つのAPIを使用する方がはるかに優れており、読みやすくなります。

Uri ParseUriOrThrow(string value);

bool TryParseUri(string value, out Uri uri);

この場合、これらのAPIが何をするかは100%明確です。

ブール値がパラメーターとして悪い理由に関する記事:http://blogs.msdn.com/jaredpar/archive/2007/01/23/boolean-parameters.aspx

于 2009-03-09T01:03:36.860 に答える
3

通常は、エラー処理メカニズムを1つ選択し、それを一貫して使用するのが最善です。この種のフリップフロップコードを許可しても、開発者の生活を実際に改善することはできません。

上記の例では、解析が失敗し、throwOnErrorがfalseの場合はどうなりますか?ここで、ユーザーは、返される場合はNULLかどうかを推測する必要があります。そうでない場合、神は知っています...

確かに、より優れたエラー処理方法として、例外と戻り値の間で継続的な議論がありますが、一貫性を保ち、選択した内容に固執することについてはコンセンサスがあると確信しています。APIはユーザーを驚かせることはできず、エラー処理はインターフェースの一部であり、インターフェースと同じように明確に定義されている必要があります。

于 2009-03-09T01:00:23.530 に答える
1

読みやすさの観点からは、ちょっと厄介です。開発者は、すべてのメソッドが例外をスローすることを期待する傾向があり、例外を無視したい場合は、自分でキャッチします。「ブールフラグ」アプローチでは、すべてのメソッドがこの例外を抑制するセマンティクスを実装する必要があります。

ただし、MSDNの記事では「throwOnError」フラグを厳密に参照していると思います。これらの場合、エラーはメソッド自体の内部で無視されるか(非表示になっているため悪い)、ある種のnull /エラーオブジェクトが返されます(一貫性がなく、それ自体がエラーであるエラーを処理するために例外を使用していないため、悪い) -傾向があります)。

あなたの例は私には問題ないようですが。例外は、メソッドがその義務を実行できないことを示します。戻り値はありません。ただし、「allowEmpty」フラグはメソッドのセマンティクスを変更します。そのため、例外であったもの(「Emptyvalue」)が予期され、正当になります。さらに、例外スローした場合、構成データを簡単に返すことはできません。したがって、この場合は問題ないようです。

于 2009-03-09T01:04:35.563 に答える
1

パブリックAPIでは、エラーが発生した場合に何が起こるかが自明ではなくなるため、障害のある状態をチェックする2つの方法を用意することは本当に悪い考えです。コードを見るだけでは役に立ちません。フラグパラメータのセマンティクスを理解する必要があります(そして、それが式であることを妨げるものは何もありません)。

nullをチェックするオプションがなく、この特定の障害から回復する必要がある場合は、後でキャッチして適切に処理できるように、特定の例外を作成することをお勧めします。それ以外の場合は、一般的な例外をスローします。

于 2009-03-09T01:06:13.407 に答える
0

これに沿った別の例は、いくつかの値型のTryParseメソッドのセットである可能性があります

bool DateTime.TryParse(string text, out DateTime)

于 2009-03-09T01:05:27.450 に答える
0

失敗によって例外が発生するのか、単にエラー表示を返すのかを示すパラメーターがあると便利なことがよくあります。そのようなパラメーターは、外部ルーチンから内部ルーチンに簡単に渡すことができるからです。次のようなものを考えてみましょう。

Byte [] ReadPacket(bool DontThrowIfNone)//なしの場合はnullを返すものとして文書化{int len = ReadByte(DontThrowIfNone); //何もない場合は-1を返すと文書化されているif(len

データの読み取り中にTimeoutExceptionのようなものが原因で例外が発生した場合、そのような例外はReadByte()またはReadMultiBytesbytes()内でスローされる必要があります。ただし、このようなデータの不足を正常と見なす必要がある場合は、ReadByte()またはReadMultiBytesbytes()ルーチンが例外をスローしないようにする必要があります。単純にdo/tryパターンを使用する場合、ReadPacketルーチンとTryReadPacketルーチンはほぼ同じコードである必要がありますが、一方はRead *メソッドを使用し、もう一方はTryRead*メソッドを使用します。イッキー。

ブール値よりも列挙型を使用する方がよい場合があります。

于 2011-10-17T17:43:50.023 に答える
0

リンク先の記事には、制御フローに例外を使用しないでくださいという注意があります。これは、質問の例に暗示されているようです。例外は、メソッド レベルの失敗を反映する必要があります。エラーをスローしても問題ないという署名があるというのは、設計が考え抜かれているように思えます。

Jeffrey Richters book CLR via C# は、「メソッドがその名前で示されているタスクを完了できない場合は、例外をスローする必要がある」と指摘しています。

彼の本は、非常によくある間違いも指摘しています。人々はすべてをキャッチするコードを書く傾向があります (彼の言葉によると、「例外の適切な使用について適切に訓練されていない開発者のどこにでもある間違いは、catch ブロックを頻繁に不適切に使用する傾向があります。例外をキャッチするとき、あなたはそれを述べていることになります。あなたはこの例外を予期しており、なぜそれが発生したのかを理解し、それに対処する方法を知っています。」)

そのため、ロジックで予期して処理できる例外をコーディングしようとしました。そうしないと、エラーになるはずです。

引数を検証して例外を防ぎ、処理できるものだけをキャッチします。

于 2009-03-09T02:45:14.463 に答える
0

donTThrowException パラメーターがあると、(どの言語でも) 例外のポイント全体が無効になります。呼び出し元のコードが必要な場合:

public static void Main()
{
        FileStream myFile = File.Open("NonExistent.txt", FileMode.Open, FileAccess.Read);
}

大歓迎です (C# にはチェック例外さえありません)。Java では、同じことが次のように達成されます。

public static void main(String[] args) throws FileNotFoundException
{
        FileInputStream fs = new FileInputStream("NonExistent.txt");
}

いずれにせよ、例外を処理する (またはしない) 方法を決定するのは呼び出し元の仕事であり、呼び出し先の仕事ではありません。

于 2009-03-09T01:21:23.213 に答える