C#“使用”语法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/149609/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 15:42:04  来源:igfitidea点击:

C# "Using" Syntax

提问by Gordon Thompson

Does the using catch the exception or throw it? i.e.

using 是捕获异常还是抛出异常?IE

using (StreamReader rdr = File.OpenText("file.txt"))
{
 //do stuff
}

If the streamreader throws an exception is it caught by using or thrown so the calling function can handle it?

如果流阅读器抛出异常,它是通过 using 捕获的还是抛出的,以便调用函数可以处理它?

采纳答案by FlySwat

using statements do not eat exceptions.

using 语句不吃异常。

All "Using" does is scope your object to the using block, and automatically calls Dispose() on the object when it leaves the block.

“Using”所做的只是将对象范围限定在 using 块中,并在对象离开块时自动调用对象上的 Dispose()。

There is a gotcha though, if a thread is forcefully aborted by an outside source, it is possible that Dispose will never be called.

但是有一个问题,如果一个线程被外部源强行中止,则 Dispose 可能永远不会被调用。

回答by hometoast

If you don't specifically catch an exception it's thrown up the stack until something does

如果你没有特别捕捉异常,它会被抛出堆栈,直到有什么事情发生

回答by Chris Marasti-Georg

usingallows the exception to boil through. It acts like a try/finally, where the finally disposes the used object. Thus, it is only appropriate/useful for objects that implement IDisposable.

using允许异常沸腾。它的作用类似于 try/finally,其中 finally 处理使用的对象。因此,它仅适用于实现IDisposable.

回答by tpower

The using does not interfere with exception handling apart from cleaning up stuff in its scope.

除了清理其范围内的内容之外,使用不会干扰异常处理。

It doesn't handle exceptions but lets exceptions pass through.

它不处理异常,但允许异常通过。

回答by harpo

"using" does not catch exceptions, it just disposes of resources in the event of unhandled exceptions.

“使用”不会捕获异常,它只是在发生未处理的异常时处理资源。

Perhaps the question is, would it dispose of resources allocated in the parentheses if an error also occured in the declaration? It's hard to imagine both happening, though.

也许问题是,如果声明中也发生错误,它会处理括号中分配的资源吗?不过,很难想象这两种情况都会发生。

回答by jop

When you see a using statement, think of this code:

当你看到 using 语句时,想想这段代码:

StreadReader rdr = null;
try
{
    rdr = File.OpenText("file.txt");
    //do stuff
}
finally
{
    if (rdr != null)
        rdr.Dispose();
}

So the real answer is that it doesn't do anything with the exception thrown in the body of the using block. It doesn't handle it or rethrow it.

所以真正的答案是它不会对 using 块的主体中​​抛出的异常做任何事情。它不处理它或重新抛出它。

回答by stephenbayer

It throws the exception, so either your containing method needs to handle it, or pass it up the stack.

它抛出异常,所以要么你的包含方法需要处理它,要么把它传递到堆栈上。

try
{
    using (
        StreamReader rdr = File.OpenText("file.txt"))
    { //do stuff 
    }
}
catch (FileNotFoundException Ex)
{
    // The file didn't exist
}
catch (AccessViolationException Ex)
{
    // You don't have the permission to open this
}
catch (Exception Ex)
{
    // Something happened! 
}

回答by Joel Coehoorn

usingguarantees* the object created will be disposed at the end of the block, even if an exception is thrown. The exception is notcaught. However, you need to be careful about what you do if you try to catch it yourself. Since any code that catches the exception is outside the scope block defined by the usingstatement, your object won't be available to that code.

using保证*创建的对象将在块的末尾处理,即使抛出异常。异常未被捕获。但是,如果您试图自己抓住它,则需要小心您所做的事情。由于捕获异常的任何代码都在using语句定义的范围块之外,因此该代码将无法使用您的对象。

*barring the usual suspects like power failure, nuclear holocaust, etc

*除了通常的嫌疑人,如电源故障、核浩劫等

回答by petr k.

You can imagine usingas a try...finallyblock without the catch block. In the finally block, IDisposable.Dispose is called, and since there is no catch block, any exceptions are thrown up the stack.

你可以想像使用一个尝试......终于没有catch块阻塞。在 finally 块中,IDisposable.Dispose 被调用,由于没有 catch 块,任何异常都会被抛出堆栈。

回答by Jeffrey L Whitledge

Any exceptions that are thrown in the initialization expression of the using statement will propagate up the method scope and call stack as expected.

在 using 语句的初始化表达式中抛出的任何异常都将按预期向上传播方法范围和调用堆栈。

One thing to watch out for, though, is that if an exception occures in the initialization expression, then the Dispose() method will not be called on the expression variable. This is almost always the behavior that you would want, since you don't want to bother disposing an object that was not actually created. However, there could be an issue in complex circumstances. That is, if multiple initializations are buried inside the constructor and some succeed prior to the exception being thrown, then the Dispose call may not occur at that point. This is usually not a problem, though, since constructors are usually kept simple.

但是,需要注意的一件事是,如果初始化表达式中发生异常,则不会在表达式变量上调用 Dispose() 方法。这几乎总是您想要的行为,因为您不想费心处理未实际创建的对象。但是,在复杂的情况下可能会出现问题。也就是说,如果在构造函数中进行了多次初始化,并且在抛出异常之前某些初始化成功,那么此时可能不会发生 Dispose 调用。不过,这通常不是问题,因为构造函数通常保持简单。