7

コンパイラ エラーを生成する次のコードがあります。

    Boolean IConvertible.ToBoolean(IFormatProvider provider)
    {
        ThrowHelper.ThrowInvalidCast(typeof(MyType), typeof(Boolean));
    }

コンパイラは、すべてのコード パスが値を返すとは限らないと不平を言っています。ここでの問題は、ThrowHelper が常にエラーをスローすることです。静的メソッドを呼び出す静的クラスです。

呼び出し後にばかげた「true を返す」ことでコンパイラを満足させることができることは理解していThrowHelperますが、それは不要なコードのように思えます。警告メッセージを抑制できることはわかっていますが、使用しようとしてもSuppressMessageAttribute、コンパイラが文句を言うのを止めません。このメソッドに対してのみこのエラーを抑制する方法はありますか?

4

3 に答える 3

10

実際に例外をスローするのではなく、ThrowHelper のメソッドで例外を作成することもできます。

Boolean IConvertible.ToBoolean(IFormatProvider provider)
{
    throw ThrowHelper.CreateInvalidCast(typeof(MyType), typeof(Boolean));
}

これにより、スタック トレースも改善される可能性があります。ThrowInvalidCast ではなく、ToBoolean を指します。

于 2011-02-14T23:24:38.423 に答える
7

エラーを修正する以外にエラーを抑制する方法はありません。

エラーは、その性質上、有効なコードを生成できないとコンパイラが認識していることを示しています。エラーを抑制する唯一の方法は、エラーを修正することです。必要なステートメントを追加し、Microsoft Connectreturnで問題を提起して、コンパイラがこれを間違っていると信じていることを示します。

ただし、呼び出しているメソッドが常にスローされることをコンパイラーが認識していないため、これは予想される動作であり、可能性のある呼び出しツリーに対して予測可能な方法でそれを判断することは、不可能ではないにしても困難であると思われます (スローで終了する前の 20 個のメソッドのチェーン)。

于 2011-02-14T23:05:21.507 に答える
3

要求された機能が問題を引き起こす可能性がある理由についての簡単な頭の体操。ThrowHelper.ThrowInvalidCastサードパーティのライブラリで定義されていると想像してください。メソッドが常にスローすることを知っていて、それについてコンパイラーに伝えるか、非常に高度な静的アナライザーが、コードがコンパイルされた瞬間にメソッドが常にスローすることを判断できる場合があります。

現在、他の開発者がそのライブラリの更新バージョンをデプロイしています。現在、メソッドは常にスローするとは限りません。突然、メソッドにリターン パスがない場合があります。そのような場合を処理するために、コンパイラ (またはランタイム) は、そのような状況で何をすべきかのバックアップ計画を含める必要があります。正しいコードを書くことで簡単に修正できるものには、かなりのオーバーヘッドがかかります。

更新: 理論的には、リターン パスのないメソッドを許可するように C# を拡張できます。Eric Lippert は、Jon Skeet の回答へのコメントで次のように述べています

「決して」メソッドは、到達可能なエンドポイントまたは return ステートメントを持つことが許可されていない単純な void メソッドです。これにより、コンパイル時に問題が解決されます。実行時に、メソッドが実際に戻り値の型のセマンティクスを正しく実装していることを確認するのは検証者の責任です。同様に、検証者は、戻り命令がなく、終点に到達できないと判断できます。

于 2011-02-14T23:17:30.640 に答える