在C#中,如果关联的catch块引发异常,是否可以强制控制通过finally块? - c#

我知道在Java中,如果catch子句捕获了异常,并且其catch块引发了异常,则控制将在线程终止之前传递与关联的finally块(如果有)。但是,在C#中似乎并非如此。

可以通过在try-catch语句的try块中放入try-finally语句和引发异常的catch块,来在C#中几乎反映出这种行为,但是,例如,如果finally块应该包含处理应记录异常的Stream Writer的代码。

有没有一种干净的方法来在C#中实现类似Java的try-catch-finally异常处理行为?

这是请求的示例代码的更新:

StreamWriter writer = new StreamWriter("C:\\log.txt");
try
{
    throw new Exception();
}
catch (Exception e)
{
    writer.WriteLine(e.Message);
    throw e;
}
finally
{
    if (writer != null)
    {
       writer.Dispose();
    }
}

将该代码添加到控制台应用程序,运行它,让重新抛出的异常不被处理,尝试删除C:\ log.txt。您将无法执行操作,因为控制从未通过过finally块。另外,如果在finally块内的某行上添加断点,您将看到它没有被命中。 (我正在使用VS2005)。

据我所知,强制控制通过finally块的唯一方法是如果重新抛出的异常是由封闭的try块的catch块处理的(如果您将上面的代码放在了try块的内部)另一个try-catch语句)。

如果未捕获到异常并允许其终止应用程序(如我提供的示例代码中所述),则控制将不会通过finally块。

在Java中会。在C#中,至少基于我所见,它不会。

参考方案

在.NET Framework中,当发生异常时,系统将确定在执行任何finally块之前是否有任何东西要捕获该异常。根据各种应用程序设置,尝试抛出将不会被捕获的异常可能会立即杀死该应用程序,而不会给任何finally块(或其他任何块)运行的机会。

如果包装了Main方法以及每个线程,

try
{
  ...
}
catch
{
  throw;
}

那么所有在try块中引发的异常都将被捕获。即使将立即重新抛出,任何嵌套的finally块也将在catch之前执行。在某些情况下,这是理想的行为。在其他情况下,可能希望例如如果不会捕获到异常,则执行一些特殊的日志记录(在某些情况下,如果finally块有机会先运行,则一个人希望记录的信息可能会被破坏)。在C#中,没有任何方法可以根据是否要捕获异常来改变一个人的动作,但是在VB.NET中,可以通过一些方法来完成。调用C#代码的VB.NET程序集可以使该代码知道是否由内部方法引发的任何异常将传播到vb.net包装器而不会被捕获。

在C#.Net中找到工作项目目录 - c#

我用过Directory.getCurrentDirectory();它只给C:\ Windows \ SysWOW64但是我需要获取Visual Studio默认项目文件夹,我该如何获取?例如:C:\ Users \ knallasi \ Documents \ Visual Studio 2010 \ Projects \ SampleApp我们如何在项…

在C#中,基本构造函数调用中的一种用法如何解决多个枚举警告? - c#

以下代码向我警告了IEnumerable可能的多个枚举:public ClassName(IEnumerable<OtherClassName> models) : base(models) { _models.AddRange(models); } 由于“基本”调用,消除此警告的常规解决方案不起作用。我无法转换为列表,因为没有地方可以存储该列表…

字段初始化程序访问“this”:在C#中无效,在Java中有效? - c#

Improve this question 一,简介:这段代码:class C { int i = 5; byte[] s = new byte[i]; } 无法编译,并出现以下错误: 字段初始值设定项不能引用非静态字段,方法或属性“C.i”Resharper说类似的话:无法在静态上下文中访问非静态字段i。这与C# spec says一致-字段初始值设定项无…

在C#中将lambda函数作为命名参数传递 - c#

编译这个简单的程序:class Program { static void Foo( Action bar ) { bar(); } static void Main( string[] args ) { Foo( () => Console.WriteLine( "42" ) ); } } 那里没什么奇怪的。如果我们在lambda…

在C++之后学习C# - c#

随着语言的发展,我一直在学习C和C++。现在,我想学习C#。我知道它们之间有一些巨大的差异-例如删除指针和垃圾回收。但是,我不知道两者之间的许多差异。C++程序员在转移到C#时需要知道的主要区别是什么? (例如,我可以使用什么代替STL,它们之间的语法差异或任何其他可能被认为重要的东西。) 参考方案 C# for C++ Developers是一个不错的起点…