C# 从 using() 语句内部返回是否有任何副作用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2369887/
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
Are there any side effects of returning from inside a using() statement?
提问by Edward Tanguay
Returning a method value from insidea using statement that gets a DataContext seems to always work fine, like this:
返回从方法值内using语句是得到一个DataContext似乎总是工作细,就像这样:
public static Transaction GetMostRecentTransaction(int singleId)
{
using (var db = new DataClasses1DataContext())
{
var transaction = (from t in db.Transactions
orderby t.WhenCreated descending
where t.Id == singleId
select t).SingleOrDefault();
return transaction;
}
}
But I always feel like I should be closing somethingbefore I break out of the using brackets, e.g. by defining transaction beforethe using statement, get it's value insidethe brackets, and then returning afterthe brackets.
但我总是觉得我应该在我打破 using 括号之前关闭一些东西,例如通过在 using 语句之前定义事务,在括号内获取它的值,然后在括号之后返回。
Would defining and returning the variable outside the using brackets be better practice or conserve resources in any way?
在 using 方括号之外定义和返回变量是更好的做法还是以任何方式节省资源?
回答by Jon Skeet
No, I think it's clearer this way. Don't worry, Dispose
will still be called "on the way out" - and only afterthe return value is fully evaluated. If an exception is thrown at any point (including evaluating the return value) Dispose
will still be called too.
不,我认为这样更清楚。别担心,Dispose
仍然会被称为“on the way out”——并且只有在返回值被完全评估之后。如果在任何时候抛出异常(包括评估返回值),Dispose
仍然会被调用。
While you certainly couldtake the longer route, it's two extra lines that just add cruft and extra context to keep track of (mentally). In fact, you don't really need the extra local variable - although it can be handy in terms of debugging. You couldjust have:
虽然你当然可以走更长的路线,但它是两条额外的线,只是添加了粗俗和额外的上下文来跟踪(精神上)。事实上,您并不真正需要额外的局部变量——尽管它在调试方面很方便。你可以只拥有:
public static Transaction GetMostRecentTransaction(int singleId)
{
using (var db = new DataClasses1DataContext())
{
return (from t in db.Transactions
orderby t.WhenCreated descending
where t.Id == singleId
select t).SingleOrDefault();
}
}
Indeed, I might even be tempted to use dot notation, and put the Where
condition within the SingleOrDefault
:
事实上,我什至可能会尝试使用点表示法,并将Where
条件放在SingleOrDefault
:
public static Transaction GetMostRecentTransaction(int singleId)
{
using (var db = new DataClasses1DataContext())
{
return db.Transactions.OrderByDescending(t => t.WhenCreated)
.SingleOrDefault(t => t.Id == singleId);
}
}
回答by Adriaan Stander
Have a look at this
看看这个
Understanding the 'using' statement in C#
The CLR converts your code into MSIL. And the using statement gets translated into a try and finally block. This is how the using statement is represented in IL. A using statement is translated into three parts: acquisition, usage, and disposal. The resource is first acquired, then the usage is enclosed in a try statement with a finally clause. The object then gets disposed in the finally clause.
CLR 将您的代码转换为 MSIL。并且 using 语句被转换为 try 和 finally 块。这就是 using 语句在 IL 中的表示方式。using 语句被翻译成三个部分:获取、使用和处置。首先获取资源,然后将用法包含在带有 finally 子句的 try 语句中。然后对象在 finally 子句中被处理。
回答by Mitch Wheat
There are noside effects of returning from inside a using()
statement.
有没有从内返回的副作用using()
声明。
Whether it makes the most readable code is another discussion.
它是否使代码最易读是另一个讨论。
回答by Kerido
I think, it's all the same. There's nothing bad in the code. The .NET framework wouldn't care where the object is created. The thing that matters is whether it is referenced or not.
我想,都一样。代码中没有什么不好。.NET 框架不会关心对象是在哪里创建的。重要的是它是否被引用。
回答by usefulBee
Yes, there can be a side effect. For example, if you use the same technique in ASP.NET MVC Action method, you will get the following error: "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection"
是的,可能会有副作用。例如,如果您在 ASP.NET MVC Action 方法中使用相同的技术,您将收到以下错误:“ObjectContext 实例已被释放,不能再用于需要连接的操作”
public ActionResult GetMostRecentTransaction(int singleId)
{
using (var db = new DataClasses1DataContext())
{
var transaction = (from t in db.Transactions
orderby t.WhenCreated descending
where t.Id == singleId
select t).SingleOrDefault();
return PartialView("_transactionPartial", transaction);
}
}