C# 从using()语句内部返回是否有任何副作用?
从获取DataContext的using语句内部返回方法值似乎总是有效的,如下所示:C# 从using()语句内部返回是否有任何副作用?,c#,using,C#,Using,从获取DataContext的using语句内部返回方法值似乎总是有效的,如下所示: public static Transaction GetMostRecentTransaction(int singleId) { using (var db = new DataClasses1DataContext()) { var transaction = (from t in db.Transactions
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;
}
}
但是我总是觉得我应该在突破using括号之前关闭某个东西,例如,在using语句之前定义transaction,在括号内获取它的值,然后在括号后返回
在使用括号外定义和返回变量是更好的做法还是节约资源?不,我认为这样更清楚。别担心,
Dispose
仍将被调用为“正在退出”-并且只有在完全计算返回值之后。如果在任何点(包括评估返回值)引发异常,仍将调用Dispose
虽然你当然可以走更长的路,但这两条额外的线路只是增加了一些粗犷和额外的背景,以便(精神上)跟踪。事实上,您并不真正需要额外的局部变量——尽管它在调试方面很方便。你可以:
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();
}
}
实际上,我甚至可能会尝试使用点表示法,并将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);
}
}
看看这个
CLR将代码转换为MSIL。
using语句得到
翻译成一个尝试和最后
块这就是使用语句的方式
以IL表示。使用
这句话翻译成三句话
部分:获取、使用和维护
处置资源是第一位的
获取,然后附上用法
在带有finally的try语句中
条款然后,对象被释放
在最后一句中
使用()语句从
内部返回时,没有副作用
它是否能产生最具可读性的代码是另一个讨论。我认为,这一切都是一样的。代码中没有什么不好的地方。NET框架不关心对象是在哪里创建的。重要的是它是否被引用。是的,可能有副作用。例如,如果在ASP.NET MVC操作方法中使用相同的技术,则会出现以下错误:“ObjectContext实例已被释放,无法再用于需要连接的操作”
只要是你@jon,在using块中抛出异常是否仍然安全?是的。使用是try/finally的简单语法糖construct@David:正如米奇所说,这很好-我已经更新了答案以使其更清楚:)为什么要将OrderByDescending与SingleOrDefault结合使用?@erikkallen:LINQ没有“MaxBy”,不幸的是-因此无法获得具有最大值的行。对于LinqTo对象,您可以相当轻松地编写自己的,但我不确定在这种情况下是否有更好的方法。你会提出什么建议呢?看看通用的IL版本可能会很有趣。我怀疑生成的IL没有什么不同。通常,我甚至不需要声明var事务——只需返回表达式的结果。这是一个有趣的见解。谢谢。这就把问题转化为:从try finally的try块返回有任何副作用吗?不,总是调用finally。如果您在using语句之外定义事务,您将得到相同的错误。在这种情况下,使用关键字是不相关的。
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);
}
}