代码之家  ›  专栏  ›  技术社区  ›  Daniel Earwicker

为什么C#不支持首次通过异常过滤?

  •  30
  • Daniel Earwicker  · 技术社区  · 17 年前

    注意:这不是 a duplicate of Jeff's question .

    那个问题被问到“是等价物吗?”我知道没有,我想知道为什么!

    Microsoft企业库的异常处理块建议我们使用以下模式:

    catch (Exception x)
    {
        if (ExceptionPolicy.HandleException(x, ExceptionPolicies.MyPolicy))
            throw;
    
        // recover from x somehow
    }
    

    该策略是在XML文件中定义的,这意味着如果客户有问题,我们可以修改该策略以帮助跟踪(或者掩盖)问题,从而为他们提供快速解决方案,直到我们正确处理该问题为止——这可能涉及与第三方争论,因为这都是谁的错。

    这基本上承认了一个简单的事实,即在实际应用程序中,如果没有这样的工具,异常类型的数量及其“可恢复性”状态实际上是不可能管理的。

    与此同时,微软的CLR团队表示这不是一个选项,事实证明这些人知道他们在说什么!问题是就在 catch 集体跑步,有吗 finally 嵌套在 try 最后 块可以执行以下任一操作:

    • 在客户的数据中丢弃一些重要的东西,因为程序状态错误到了未知的程度。
    • 另一个 例外,增加了普遍的混乱和痛苦。

    请注意 using 语句和C++/CLI析构函数是基于 尝试 最后 ,所以他们也受到影响。

    接住 / throw 过滤异常的模式不好。实际上需要的是一种通过策略过滤异常的方法,而不实际捕获异常,从而触发异常的执行 块,除非我们找到一个告诉我们异常可以安全恢复的策略。

    CLR团队最近在博客上对此进行了讨论:

    结果是,我们必须在VB.NET中编写一个helper函数,以允许我们从C#访问这一重要功能。有问题的一个重要线索是,BCL中有这样做的代码。很多人都在博客上写过这件事,但他们很少提到这件事 尝试 /

    • 在这个问题上,是否有来自C#团队的公开声明或直接电子邮件?
    • 是否有任何现有的Microsoft Connect建议要求这样做?我听过关于它们的谣言,但没有一个可能的关键词出现任何东西。

    更新: 如上所述,我已经在Microsoft Connect上搜索过,但没有找到任何内容。我也(毫不奇怪)用谷歌搜索过。我只找到了人 explaining why they need this feature ,或指出 advantages of it in VB.NET ,或是毫无结果地希望 added in a future version of C# working around it ,还有很多 misleading advice

    更新2: 建立 an interesting old blog post from Eric Gunnerson 前C#团队成员:

    “是的,能够对 接球比较方便 而不是写测试 你需要做任何新的事情。”

    这和我之前的假设是一样的,直到我得到了正确的解释!

    6 回复  |  直到 9 年前
        1
  •  4
  •   JaredPar    17 年前

    至于任何现有的连接错误。以下问题涉及异常传单。用户没有明确声明他们希望它们在何时执行的意义上是一个实际的过滤器,但这是由逻辑暗示的。

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

    除此之外,我找不到或知道的任何问题都与您正在寻找的有关。我认为最好有一个单独的问题,明确指出需要VB.Net风格的异常过滤器。

    至于从C#团队获得正式响应的部分,当你1)提交一个连接错误或2)被主要错误欺骗时,你很可能会得到。我真的怀疑现在是否有官方的理由。

    这是我的 在这个问题上:我的猜测是,这个功能根本不在最初的C#1.0功能集上,而且从那时起,没有足够的需求将其融入到语言中。C#和VB团队在每个船舶周期开始时花费了难以置信的时间对语言功能进行排序。我们得做点什么 有时很难切割。如果没有足够的需求,一个特性进入语言的可能性很小。

    直到最近,我敢打赌,你很难找到十分之一的人理解VB.Net的Try/When与在C#catch块中使用简单的旧if语句之间的区别。最近人们似乎更关注它,所以它可能会成为langauge的未来版本。

        2
  •  2
  •   Steve Steiner    17 年前

    使用 Exception Filter Inject 可能比使用代理解决方案更简单。

    the C# design team is interviewed .

    我猜当最初的决定做出时,异常过滤器被视为一种不必要的复杂情况,可能弊大于利。在本次访谈中,您当然可以看到对未经验证的功能保持“沉默”的愿望,即决定不支持检查异常: The Trouble with Checked Exceptions .

    我认为postmoterm诊断场景强烈支持使用该语言提供对异常过滤器的访问。然而,当时可能没有阐明这些情景。此外,这些场景确实需要适当的工具支持,这在V1中肯定不可用。最后,添加此功能可能会带来一些我们没有考虑的负面影响。

    如果这上面没有连接错误,你应该输入一个并鼓励其他人投票支持它。[我建议要求访问CLR功能,而不是试图设计它如何适合该语言。]

        3
  •  1
  •   andleer    17 年前

    我也不相信Java有过滤器选项。我猜如果是的话,我们也会在C#中看到一个。考虑到VB团队一开始就一帆风顺,VB.net很可能有一个偶然的机会。

    在未来的C#版本中,有一件事可能对您有利,那就是微软明确的目标是在未来的C#版本和VB.net版本中保持语言功能的对等。我将在此基础上提出我的论点。

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

        4
  •  0
  •   casperOne    17 年前

    关于第一个问题,如果有一个公开声明,那么它很可能被放在网络上的某个地方,在这种情况下,谷歌应该找到一些东西(如果它存在的话)。

    如果这是一封与C#团队的直接电子邮件,那么它很可能属于保密协议,因此无论如何都无法发布。

    关于第二个问题,Microsoft Connect上有一个搜索功能,在输入新建议之前,他们会提示您使用该功能。如果你找不到它,那么可能就没有了。

    我的建议是提出一个建议,然后加以推广,让其他人参与进来。

        5
  •  0
  •   Andrey Shchekin    17 年前

    据我所知,在rethrow的时候,内部函数中的finally处理程序被执行,这就是给您带来问题的原因。

    所以,除非我误解了什么,否则使用语言支持的异常过滤器并没有什么好处。

        6
  •  0
  •   supercat    14 年前

    我至少可以想出两个原因来解释为什么C中没有异常过滤#

    我很想在C#和vb中看到的一个特性是可选的,它需要使用异常过滤器来实现,但不需要直接公开它们 Exception a的参数 finally 块这个参数应该是 null 例外 参数除了用于检查 无效的 (这意味着该功能相当于公开 fault 最后 最后 -阻止异常或覆盖预先存在的异常。使早期的异常可用于