注意:这不是a duplicate of Jeff's question。
那个问题是“是等同的吗?”我知道没有,我想知道为什么!
我问的原因是我只是清楚它的重要性,结论对我来说似乎很奇怪。
Microsoft企业库的异常处理块建议我们使用此模式:
catch (Exception x)
{
if (ExceptionPolicy.HandleException(x, ExceptionPolicies.MyPolicy))
throw;
// recover from x somehow
}
策略是在XML文件中定义的,这意味着如果客户遇到问题,我们可以修改策略以帮助跟踪问题(或者可能还有问题),以便在我们处理之前快速解决问题适当地 - 这可能涉及与第三方争论,关于谁的错。
这基本上是对一个简单事实的承认,即在没有像这样的设施的情况下,在实际应用中,例外类型的数量及其“可恢复性”状态实际上是不可能管理的。
与此同时,MS的CLR团队表示这不是一个选择,事实证明这些人知道他们在谈论什么!问题是在catch
块运行之前,嵌套在finally
块内的任何try
块都将被执行。因此,这些finally
块可能会执行以下任何操作:
请注意,using
语句和C ++ / CLI析构函数构建在try
/ finally
之上,因此它们也会受到影响。
很明显,用于过滤异常的catch
/ throw
模式并不好。实际需要的是一种通过策略过滤异常而不实际捕获它们从而触发finally
块执行的方法,除非我们找到一个告诉我们异常可以安全恢复的策略。
CLR团队最近在博客中发表了这篇文章:
结果是我们必须在VB.NET中编写一个辅助函数,以允许我们从C#访问这个重要的功能。存在问题的一个重要线索就是BCL中有代码可以做到这一点。很多人都写过关于这样做的博客,但他们很少提及关于try
/ finally
块的事情,这是杀手。
我想知道的是:
更新:如上所述,我已经在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 。但没有声明从所有当前版本的C#中省略它的理由。我询问现有Connect问题的原因是:(a)我没有创建不必要的副本;(b)我可以告诉感兴趣的人我是否必须创建一个。
更新2:找到an interesting old blog post from Eric Gunnerson,以前是C#团队:
“是的,能够制定条件 捕获更方便一些 而不是必须写测试 你自己,但它并没有真正实现 你要做任何新事。“
在我向我正确解释之前,我的假设是一样的!
答案 0 :(得分:4)
对于任何现有的连接错误。以下问题涉及异常过滤器。用户没有明确说明他们希望它们在执行时的意义上是一个实际的过滤器,但恕我直言的是逻辑所暗示的。
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=401668
除了这个问题,我没有找到或知道与您正在寻找的问题有关的问题。我认为有一个单独的问题明确地调出了对VB.Net样式异常过滤器的需求会很好。
如果您已经做了一些尽职调查以寻找现有问题,我不会过于担心引入重复的问题。如果有嫌疑人,Mads将相应地欺骗它并将您链接到主要请求。
至于从C#团队获得官方回复的部分,当你要么1)提交连接错误或者2)对主要错误进行欺骗时,你可能会得到这个。我真的怀疑现在有正式的理由/理由。
这是关于这个问题的猜测:我的猜测是这个功能根本不在原始的C#1.0功能集上,因为那时候没有足够的需求让它进入语言。 C#和VB团队在每个船舶周期开始时花费了令人难以置信的时间排名语言功能。我们有时必须做出一些非常的难度削减。没有足够的需求,一个功能很少有机会进入语言。
直到最近,我打赌你很难找到10个人中的1个,他们了解VB.Net的Try / When之间的区别,并且只是在C#catch块中使用普通的旧if语句。它最近似乎对人们的思想更多,所以它可能会成为未来版本的语言。
答案 1 :(得分:2)
使用Exception Filter Inject可能比使用委托解决方法更简单。
要真正回答您的问题,您需要Anders Hejlsberg或原设计会议中的人员的回复。你可能会试着看看第9频道的采访者是否可以在下次the C# design team is interviewed时询问。
我猜想,在做出最初决定时,异常过滤器被认为是一种不必要的并发症,可能弊大于利。在本次访谈中,您肯定会看到一种对未经证实的功能保持“沉默”的愿望,即不支持已检查的例外情况:The Trouble with Checked Exceptions 。
我认为postmoterm诊断方案强烈要求提供对该语言中的异常过滤器的访问。然而,当时可能尚未阐明这些情景。此外,这些场景确实需要适当的工具支持,这在V1中肯定不可用。最后,添加我们没有考虑的这个功能可能会有很大的负面影响。
如果没有连接错误,您应该输入一个并鼓励其他人投票。 [我建议要求访问CLR功能,而不是尝试设计它如何适合该语言。]
答案 2 :(得分:1)
我不相信Java也有过滤选项。猜测如果确实如此,我们也会在C#中看到一个。鉴于VB团队以干净利落的方式开始,VB.net可能有一次机会。
对于在未来版本的C#中获得此选项可能对您有利的一件事是Microsoft声明的目标是在未来版本的C#和VB.net中保持laguage功能之间的平等。我会基于此提出我的论点。
http://www.chriseargle.com/post/2009/01/Parity-Between-Languages.aspx
答案 3 :(得分:0)
关于第一个问题,如果有一个公开声明,那么它很可能会放在网上的某个地方,在这种情况下,谷歌应该出现一些东西(如果存在的话)。
如果它是与C#团队的直接电子邮件,那么它很可能是在NDA下,因此无论如何都无法发布。
关于第二个问题,Microsoft Connect上有一个搜索功能,它们会在输入新建议之前提示您使用。如果找不到,那么可能没有。
我的建议是提出一个建议,然后进行宣传,让别人对此进行权衡。
答案 4 :(得分:0)
据我理解,在重新抛出的那一刻,内部函数中的最终处理程序被执行,这就是为你创造问题的原因。
但是,假设您有一个异常过滤器,可以通过异常而不实际重新抛出异常。你仍然需要以某种方式处理它,你会遇到同样的问题(最终效果)。
因此,除非我误解了某些内容,否则使用语言支持的异常过滤器并没有太大的收获。
答案 5 :(得分:0)
我至少可以想到为什么C#
中缺少异常过滤的两个原因我真的很想在C#和vb中看到一个功能,它需要使用异常过滤器来实现但不需要直接公开它们,这将是{Exception
的可选参数。 1}}阻止。如果没有发生未捕获的异常,则此参数为finally
;否则它将保留有问题的例外。这将允许程序在发生异常时想要执行某些操作但实际上不“处理”它的情况。在大多数情况下,除了检查null
(意味着该功能等同于公开Exception
块)之外,null
参数不会用于任何事情,但它会提供优势清理期间发生异常的情况。目前,如果在fault
块期间发生异常,则必须扼杀finally
- 阻止异常或覆盖预先存在的异常。让finally
块代码可用的早期异常使它能够包装或记录它。