我只是想知道为什么C#语言不允许你在如下的using语句之后包含一个catch块:
using(var MyObject = new MyObject())
{
// do work
}
catch(Exception ex)
{
// log/handle exception
}
这个问题已存在很长时间了,它看起来像一个易于实现的功能,没有任何负面影响,实际上几乎每个程序员都会使用它。是否有正当理由认为C#语言尚未更新以允许此功能,或者是否对该功能的需求不足?
编辑:下面我的评论中有一个(或更多?)提到了WCF使用块的缺点。然而,我后来意识到我错误,因为它适用于这个对话,因为问题是在(自动生成的)finally块中引发异常,而我在这里要求的是访问catch块之间的尝试,最后如果using语句生成一个。
答案 0 :(得分:6)
回答"的主要问题:如何结合异常处理和使用构造"。答案通常是在我的情况下,我没有。我的大多数异常处理都是在调用堆栈的更高点处理的,集中处理以简化日志记录并知道下一步该做什么(例如,如果我枚举了一组项目,我会在枚举步骤中捕获它以允许我记录该项目失败但继续其余项目。)
但是,如果我将两者结合起来,我会将using
包装在try / catch中。您在其他地方提到了使用WCF对象执行此操作的问题,因为它们倾向于使用Dispose()
方法抛出。在这种情况下,我会遵循微软的建议而不是完全使用它们,而是手动扩展它们。
我甚至会为finally
块添加逻辑,该块具有必要的逻辑,以确保在不会引发异常的情况下不调用Dispose()
。
要回答有关新语言功能的问题,您的分析不正确。
此问题已存在很长时间
什么问题?你指出了一个潜在的句法结构而没有证明目的,并声称它很重要。在添加之前,句法结构面临着很大的特征要求。
WCF周围存在一个小问题,但它听起来像是API问题,而不是语言设计问题。如果您仔细阅读建议,他们会有效地说"关闭连接不是免除异常,因此在此之前手动验证是否安全#34;。
它似乎是一个易于实现的功能
研究using
构造,您将重新构建它实际上很复杂。 using
构造扩展为:(大约)
MyObject MyObject;
try
{
MyObject = new MyObject()
// do work
}
finally
{
if (MyObject != null)
MyObject.Dispose();
}
通过添加catch
,您需要对事物进行重新排序,以便按照正确的语法顺序进行操作(因为catch
在finally
之前发生)。
没有不良影响
你可能已经注意到了,但我忽略了为什么这是错误的。 catch
去哪儿了?您是否将其添加为第二个try
以确保在执行catch
块之前处置对象(与语法中的明显顺序相匹配)或者是否在finally之前添加它?
前者很难自己用try
来实现,而后者很难理解,并且可能无论如何都无法正常工作,因为你没有在隐式中捕获异常{ {1}}阻止。
实际上几乎每个程序员都会使用
大多数人永远不会这样做,而是更喜欢使用显式finally
/ try
来确保try / catch的目的是明确的。还要注意过度使用try / catch,因为这是一个不好习惯。
答案 1 :(得分:3)
您可以通过将try包装在try块中轻松实现此目标,因此:
try
{
using (var MyObject = new MyObject())
{
//do work
}
}
catch (Exception ex)
{
//handle exception.
}
所以问题就变成了,为什么设计师将异常处理的概念(即try
/ catch
)块与资源处置的概念联系起来(即using
声明)?它会使语言进一步复杂化,因为现在不是一个明确定义的地方catch
可以出现,(try
之后)它现在还有其他规则(为什么停止使用?为什么不说你可以在任意catch
对之后添加{}
?)
对于会增加混淆并且不会增加任何实际价值的功能,可能不值得努力。