1

私は最近 .NET Contracts API を発見しました。拡張構文ではなくメソッドを使用した実装方法は好きではありませんが (私の意見では、 Sing#は適切でした)、古い/通常の方法よりもそれらを使用する方が好きです。 null チェックなどに if を使用します。

また、最初の Contract.Ensures-calls に近づいていて、実行中に例外が発生した Contract.Ensures を含むメソッドで例外をどのように処理するかという質問に出くわしました。

契約という言葉。メソッド内で例外を処理し、クラスを正しい状態に戻す必要があるように感じますが、それができない場合はどうすればよいでしょうか?

ここにこのクラスがあるとしましょう:

public class PluginManager
{
    private ILoadedFromAtCompileTimeUnknownAssembly extension;

    public bool IsFinished { get; private set; }

    public void Finish()
    {
        extension.Finish();
        this.IsFinished = true;
    }
}

メソッドの完了後に IsFinished が true であることを確認するために Contract.Ensures を使用できますか?

4

2 に答える 2

2

はい。保証は基本的に「メソッドが正常に終了するかどうかを保証する」、つまり例外なしを意味します。

于 2013-10-21T08:12:11.113 に答える
1

コード コントラクトの概念を正しく理解するのは非常に難しいと思います。コード コントラクトは、プログラミング エラーを見つけるためのものです。そのように適用すると、リリース ビルドのコントラクトを削除でき、アプリケーションは引き続き完全に機能します。

しかし、プログラミング (論理エラー) と構成および入力データの問題を区別することは非常に困難です。これらのチェックは、リリース ビルドに残す必要があります。したがって、コード コントラクトを使用して拡張機能/プラグインが正しく読み込まれたかどうかを確認することはお勧めできません。これは通常、アプリケーションに構成されているためです。リリース ビルドでコントラクトを削除すると、デバッグ ビルドまたはリリース ビルドでアプリを間違って構成したかどうかに応じて、アプリケーションの動作が異なります。

契約違反は 1 つの例外タイプのみで報告されます。これにより、アプリケーションの上位層で、構成の問題やアプリケーションのロジック バグなどに対応することができなくなります。反応を使用して、続行するつもりはありませんが、リモートで役立つメッセージをユーザー/開発者に提示することを意味します。

Code Contract は表面的には良さそうに見えますが、ほとんどの人が間違った使い方をしているのではないかと心配しています。メソッドの入力検証のための null チェックをすべて置き換えることを意図したものではありません。入力データではなくロジックの問題が根本的な原因であることが確実なコード コントラクトで null チェックを行うメソッドのみを置き換える必要があります。

コンソール アプリケーションなどで入力としてファイル名が必要で、ユーザーがコマンド ラインでファイル名を指定するのを忘れた場合、ContracException でユーザーに挨拶するのは得策ではありません。

  • エラー メッセージは、ユーザーを混乱させる可能性があります。
  • プログラミング エラーとユーザー入力検証の問題を区別することはできません。
  • 例外の種類が内部であるため、特定の ContractException をキャッチすることはできません。

ユーザー ドキュメントを参照してください。

7.6 ContractException ContractException 型はパブリック型ではなく、ランタイム コントラクト チェックが有効になっている各アセンブリにネストされたプライベート型として発行されます。したがって、 ContractException のみをキャッチする catch ハンドラを作成することはできません。したがって、コントラクトの例外は、一般的な例外のバックストップの一部としてのみ処理できます。この設計の理論的根拠は、プログラムが ArgumentNullException や同様の検証例外をキャッチしてはならないのと同様に、コントラクトの失敗に依存する制御ロジックをプログラムに含めるべきではないということです。

于 2013-10-21T08:53:25.013 に答える