なぜC#が初回通過例外フィルタリングをサポートしていないのですか?

StackOverflow https://stackoverflow.com/questions/602066

  •  03-07-2019
  •  | 
  •  

質問

注:これはジェフの質問の複製ではありません。

その質問は「同等のものですか?」と尋ねました。存在しないことはわかっていますが、その理由を知りたいです!

私が尋ねる理由は、それがどれほど重要であるかを明確にしただけであり、結論は私にとって非常に奇妙に思えるからです。

Microsoftのエンタープライズライブラリの例外処理ブロックは、次のパターンを使用することを推奨しています。

catch (Exception x)
{
    if (ExceptionPolicy.HandleException(x, ExceptionPolicies.MyPolicy))
        throw;

    // recover from x somehow
}

ポリシーはXMLファイルで定義されているため、顧客が問題を抱えている場合は、ポリシーを変更して問題を追跡(またはペーパーオーバー)し、対処するまで迅速に解決できるようにすることができます。それを適切に-サードパーティとの議論を伴う可能性があり、誰のせいなのか。

これは基本的に、実際のアプリケーションでは例外タイプの数とその「回復可能性」がこのような機能がないと、ステータスを管理することは事実上不可能です。

一方、MSのCLRチームは、これはオプションではないと言います。そして、彼らは彼らが話していることを知っていることがわかりました!問題は、 catch ブロックが実行される直前に、 try ブロック内にネストされた finally ブロックが実行されることです。したがって、これらの finally ブロックは次のいずれかを実行できます。

  • プログラムの状態を無害に変更します(phew、lucky)。
  • プログラムの状態が未知の程度までねじ込まれているため、顧客のデータで重要なものを破棄します。
  • 特にネイティブコードの呼び出しについて話している場合は、問題を診断する必要があるという重要な証拠を偽装または破棄します。
  • 一般的な混乱と悲惨さを増す別の例外を投げます。

using ステートメントとC ++ / CLIデストラクタは try / finally 上に構築されているため、それらも影響を受けることに注意してください。

したがって、例外をフィルタリングするための catch / throw パターンは明らかに良くありません。実際に必要なのは、例外を安全に回復できるというポリシーが見つからない限り、実際にキャッチせずに finally ブロックの実行をトリガーすることなく、ポリシーを介して例外をフィルタリングする方法です。

CLRチームはこのことについて最近ブログに書きました:

結果として、C#からこの重要な機能にアクセスできるようにするには、VB.NETでヘルパー関数を作成する必要があります。問題があるという大きな手がかりは、これを行うBCLのコードがあることです。多くの人々がそれを行うことについてブログに書いていますが、 try / finally ブロックに関することについて言及することはめったにありません。これはキラーです。

知りたいのは:

  • この件に関してC#チームから受け取った公式声明や直接のメールはありますか?
  • これを求める既存のMicrosoft Connectの提案はありますか?私はそれらの噂を聞いたことがありますが、ありそうなキーワードは何も見つかりませんでした。

更新:上記のように、私はすでに何も見つけられずにMicrosoft Connectで検索しました。私も(当然のことながら)Googleを利用しています。 この機能が必要な理由を説明している、または指摘している人しかいない

役に立ちましたか?

解決

既存の接続バグについて。次の問題は、例外フィルターを扱います。ユーザーは、いつ実行するかという意味で実際のフィルターにしたいということを明示的に述べていませんでしたが、ロジックによって暗黙に示されています。

https://connect.microsoft.com/VisualStudio/feedback /ViewFeedback.aspx?FeedbackID=401668

しかし、その問題に加えて、あなたが探しているものに関連する、私が見つけたり知ることができる問題はありません。 VB.Netスタイルの例外フィルターの必要性を明示的に呼び出す別の問題があるとよいと思います。

既存の質問を探してデューデリジェンスを少し行っていれば、重複した質問を導入することについてあまり心配しません。デュープがある場合、Madsはそれに応じてデュープし、メインリクエストにリンクします。

C#チームから公式の回答を得る部分に関しては、1)接続バグを提出するか、2)メインバグに対してだまされると、おそらくそれを得るでしょう。公式の理由/正当化が今そこにあるとは本当に疑います。

この問題についての私の推測:私の推測では、この機能は元のC#1.0機能セットになかっただけで、それ以来、十分な需要がありませんでした。言語。 C#およびVBチームは、すべての出荷サイクルの開始時に、言語機能のランキングに信じられないほどの時間を費やしています。時々非常に難しいカットをする必要があります。十分な需要がなければ、機能が言語に組み込まれる可能性はほとんどありません。

最近まで、VB.NetのTry / Whenと、C#catchブロックで単純な古いifステートメントを使用することの違いを理解している10人のうち1人を見つけるのは難しいでしょう。それは最近人々の心にもう少しあるようですので、多分それは言語の将来のバージョンになるでしょう。

他のヒント

Exception Filter Inject を使用すると、デリゲートの回避策を使用するよりも簡単になります。

質問に対する本当の答えを得るには、Anders Hejlsberg、または元の設計会議に参加した人からの応答が必要です。次回チャンネル9のインタビュアーから質問されるかどうかを確認してみてください。 C#設計チームにインタビューします

元の決定が下されたとき、例外フィルターは不要な合併症とみなされ、それは良いことよりも害をもたらす可能性があると思います。このインタビューでは、確認済みの例外をサポートしないという決定について、実証されていない機能について「沈黙」を保ちたいという願望を確かに見ることができます:チェック済み例外の問題

事後診断シナリオは、言語の例外フィルターへのアクセスを提供することを強く主張していると思います。ただし、これらのシナリオは当時明確にされていなかった可能性があります。また、これらのシナリオには、適切なツールサポートが本当に必要であり、V1では使用できませんでした。最後に、この機能を追加することに関して、私たちが検討していない大きなマイナス面があるかもしれません。

これに接続バグがない場合は、それを入力し、他の人に投票を勧める必要があります。 [CLR機能が言語にどのように適合するかを設計するのではなく、CLR機能へのアクセスを要求することをお勧めします。]

Javaにもフィルターオプションがあるとは思わない。もしそうなら、C#にも表示されると思います。 VB.netは、VBチームが白紙の状態から始めたことを考えると、偶然1つを持っている可能性があります。

C#の将来のバージョンでこのオプションを取得する限り、C#とVB.netの将来のバージョンで言語機能間の同等性を維持するというMicrosoftの目標は、あなたに有利になる可能性があることの1つです。それに基づいて議論を進めます。

http://www.chriseargle.com/post /2009/01/Parity-Between-Languages.aspx

最初の質問に関して、公的な声明があった場合、それはおそらくどこかでウェブに掲載されました。

C#チームへの直接のメールである場合は、NDAの下にある可能性が高いため、とにかく公開できません。

2番目の質問では、Microsoft Connectに検索機能があり、新しい提案を入力する前に使用するように求められます。見つからない場合は、おそらくないでしょう。

推奨事項は、提案を入力し、それを宣伝して他の人に検討してもらうことです。

それらを理解すると、再スローの時点で、内部関数のfinallyハンドラーが実行され、それが問題を引き起こします。

しかし、実際に再スローせずに例外を通過させる例外フィルターがあるとします。どうにかしてどこかでそれを処理する必要があり、そこで同じ種類の問題(最終的な影響)で実行されます。

そのため、何かを誤解していない限り、言語でサポートされている例外フィルターを使用しても大きなメリットはありません。

C#には例外フィルタリングが存在しない少なくとも2つの理由が考えられます

  1. 例外フィルターを許可すると、プログラマーは、 'catch'または 'finally'内で安全に実行できたとしても、その時点では安全ではない最初のパスの例外処理中に何かを行うことを奨励できます。たとえば、「try」内のコードがブロックはロックを取得し、ロックが保持されている間に例外をスローします。ロックは外側の例外フィルターの実行中に保持されますが、外側の「キャッチ」の前に解放されます。または「最終的に」」ブロックが実行されます。また、少なくとも最後にチェックしたとき、例外フィルター内で発生し、その中にキャッチされなかった例外は静かに抑制されました-ugい状況です。
  2. C#の実装者は、言語を「フレームワークに依存しない」ものにするというビジョンを持っています。 C#が.net初回通過フィルタリングをサポートしている場合、その機能を使用したプログラムは、例外を異なる方法で処理するフレームワークでは使用できない可能性があります。これは、C#がプログラムが `Object.Finalize()`をオーバーライドすることを禁止するのと同じ理由です。 `Object.Finalize()`を取り巻く推論には欠陥があります(デストラクタを正しく使用するには他のプラットフォーム固有のメソッドを使用する必要があるため、 `Object.Finalize()`にデストラクタ構文を使用することはt77o欠陥のあるソフトウェア)推論は、例外フィルターに関してある程度意味があります。一方、その問題に対処する適切な方法は、例外フィルターを直接公開していなくても、例外フィルター関連の機能を公開することです。

C#とvbで本当に見たい機能の1つは、実装するために例外フィルターを使用する必要がありますが、直接公開する必要はないため、オプションの Exception パラメーター finally ブロック。キャッチされない例外が発生しない場合、このパラメーターは null になります。それ以外の場合は、問題の例外が保持されます。これにより、例外が発生したときにプログラムが何かを実行したいが、実際には「ハンドル」ではない状況が可能になります。それ。ほとんどの場合、 Exception パラメーターは、 null のチェック以外には使用されません(つまり、この機能は fault を公開することと同じです)ブロック)、ただし、クリーンアップ中に例外が発生した場合に利点があります。現在、 finally ブロック中に例外が発生した場合、 finally -block例外を抑制するか、既存の例外を上書きする必要があります。 finally ブロックコードで以前の例外を利用できるようにすると、ラップまたはログ記録が可能になります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top