Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 最后一块的意义是什么?_.net_Design Patterns_Exception_Try Catch Finally - Fatal编程技术网

.net 最后一块的意义是什么?

.net 最后一块的意义是什么?,.net,design-patterns,exception,try-catch-finally,.net,Design Patterns,Exception,Try Catch Finally,撇开语法不谈,它们之间的区别是什么 try { } catch() { } finally { x = 3; } 及 编辑:在.NET2.0中 所以 在行为上是等效的吗?因此您可以清除在try块中初始化的任何打开的连接等。如果您打开了一个连接,然后发生了一个异常,那么该异常将无法正确关闭。这种类型的场景就是finally块的用途。在Java中: 最后总是被调用,不管catch()中是否正确捕获了异常,或者实际上是否有捕获。取决于语言,因为可能存在一些细微的语义差异,但其思想是,即使t

撇开语法不谈,它们之间的区别是什么

try {
}
catch() {
}
finally {
    x = 3;
}

编辑:在.NET2.0中


所以


在行为上是等效的吗?

因此您可以清除在try块中初始化的任何打开的连接等。如果您打开了一个连接,然后发生了一个异常,那么该异常将无法正确关闭。这种类型的场景就是finally块的用途。

在Java中:


最后总是被调用,不管catch()中是否正确捕获了异常,或者实际上是否有捕获。

取决于语言,因为可能存在一些细微的语义差异,但其思想是,即使try块中的代码抛出异常,它也将(几乎)始终执行

在第二个示例中,如果catch块中的代码返回或退出,则不会执行x=3。首先,它会

在.NET平台中,在某些情况下不会执行finally块:
安全异常、线程挂起、计算机关闭等。

首先,如果返回try块,finally仍将运行,但try-catch-finally块下面列出的代码将不会运行。

无论是否捕获异常,finally块都应该执行。
请参见

在try和catch为空的情况下,没有区别。否则您可以确定,finally将被执行

例如,如果您在catchblock(rethrow)中抛出一个新异常,那么只有在finally块中才执行分配

通常情况下,finally用于自己清理(关闭数据库连接、文件句柄等)


您不应该在finally中使用控制语句(return、break、continue),因为这可能是维护的噩梦,因此被认为是不好的做法

finally块将始终被调用(实际上不是…),即使抛出异常或到达return语句(尽管这可能与语言有关)。这是一种清理的方法,你知道它将永远被调用。

< P>,你可能会想到一些类似于<代码> catch(…)>代码>,它在C++中捕获一个非指定的异常。 但是,
finally
是无论
catch
块中发生什么都将执行的代码


Microsoft在

上有一个帮助页面,finally块与try/catch块在同一范围内,因此您可以访问其中定义的所有变量

假设您有一个文件处理程序,这就是它编写方式的不同

try
{
   StreamReader stream = new StreamReader("foo.bar");
   stream.write("foo");
}
catch(Exception e) { } // ignore for now
finally
{
   stream.close();
}
相比

StreamReader stream = null;
try
{
    stream = new StreamReader("foo.bar");
    stream.write("foo");
} catch(Exception e) {} // ignore

if (stream != null)
    stream.close();

但请记住,里面的任何东西最终都不能保证运行。想象一下,您收到一个中止信号,windows崩溃或断电。对业务关键代码依赖finally是错误的。

即使在发生未处理的异常时,finally中的任何代码都会在中运行。通常,finally代码用于使用.dispose()清理非托管代码的本地声明。

try-catchfinally是一个非常重要的构造。您可以确定,即使抛出异常,finally块中的代码也将被执行。在处理外部资源时,释放它们是非常重要的。垃圾收集不会帮你的。在最后一部分中,您不应该使用return语句或抛出异常。这样做是可能的,但这是一种不好的做法,可能会导致不可预测的结果

如果您尝试此示例:

try {
  return 0;
} finally {
  return 2;
}
结果将是2:)


与其他语言的比较:

作为一名开发人员,Finally blocks允许您在try{}块遇到错误时自行清理,并且有其他人指出,这主要是在释放资源的保护伞下-关闭指针/套接字/结果集,将连接返回到池等

@mats是非常正确的,始终存在“硬”故障的可能性-最终块不应包括任务关键型代码,这些代码应始终在try{}内以事务方式完成

@再次使用mats—真正的美妙之处在于,它允许您从自己的方法中抛出异常,并且仍然保证您可以整理:

try
{
StreamReader stream = new StreamReader("foo.bar");
mySendSomethingToStream(stream);
}
catch(noSomethingToSendException e) {
    //Swallow this    
    logger.error(e.getMessage());
}
catch(anotherTypeOfException e) {
    //More serious, throw this one back
    throw(e);
}
finally
{
stream.close();
}

因此,我们可以捕获多种类型的异常,以不同的方式处理它们(第一种异常允许执行try{}之外的任何异常,第二种异常有效地返回),但总是整洁地清除。

有几件事使finally块变得有用:

  • 如果您从try或catch块返回,那么finally块仍将在控制权返回给调用函数之前执行
  • 如果catch块中发生异常,或者try块中发生未捕获类型的异常,那么finally块中的代码仍会执行
  • 这些功能使最终块非常适合关闭文件句柄或套接字。

    @iAn和@mats:

    作为一项规则,我不会在try{}中“拆掉”任何在try{}中“设置”的东西。最好将流创建拉到try{}之外。如果您需要处理流上的异常,可以在更大的范围内创建

    StreamReader stream = new StreamReader("foo.bar");  
    try {
        mySendSomethingToStream(stream);
    }
    catch(noSomethingToSendException e) {
        //Swallow this    
        logger.error(e.getMessage());
    }
    catch(anotherTypeOfException e) {
        //More serious, throw this one back
        throw(e);
    }
    finally {
        stream.close();  
    }
    

    在Java中,无论是使用“return”、只是运行try块还是捕获异常,都可以将它用于任何要执行的操作

    例如,关闭数据库会话或JMS连接,或取消分配某些OS资源

    我猜它在.NET中是类似的?

    这个问题很老了,但这一直困扰着我(我在这里找到它是有原因的)。我已经阅读了每一个答案,在我看来,没有人真正想清楚了

    这不是答案。我真的认为
    最终没有什么好处,这可能就是为什么它直到“最近”才出现在编程语言中。大多数说明
    stream.close()
    的示例都会导致null引用异常,因此您仍然需要测试它是否为null

    Y
    try
    {
    StreamReader stream = new StreamReader("foo.bar");
    mySendSomethingToStream(stream);
    }
    catch(noSomethingToSendException e) {
        //Swallow this    
        logger.error(e.getMessage());
    }
    catch(anotherTypeOfException e) {
        //More serious, throw this one back
        throw(e);
    }
    finally
    {
    stream.close();
    }
    
    StreamReader stream = new StreamReader("foo.bar");  
    try {
        mySendSomethingToStream(stream);
    }
    catch(noSomethingToSendException e) {
        //Swallow this    
        logger.error(e.getMessage());
    }
    catch(anotherTypeOfException e) {
        //More serious, throw this one back
        throw(e);
    }
    finally {
        stream.close();  
    }