ChatGPT解决这个技术问题 Extra ChatGPT

从 using() 语句内部返回是否有任何副作用?

从获取 DataContext 的 using 语句中返回方法值似乎总是可以正常工作,如下所示:

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 语句之前定义事务,在括号内获取它的值,然后在括号之后返回。

在使用括号之外定义和返回变量会是更好的做法还是以任何方式节省资源?

查看通用 IL 的变体可能会很有趣。我怀疑生成的 IL 几乎没有什么区别。我通常甚至不会费心声明 var 事务 - 只需返回表达式的结果。

J
Jon Skeet

不,我认为这样更清楚。不用担心,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);
    }
}

没错,是你@jon,如果在 using 块内引发异常,它仍然安全吗?
是的。 using 只是 try/finally 构造的语法糖
@David:正如米奇所说,这很好 - 我已经更新了答案以使其更清楚:)
为什么将 OrderByDescending 与 SingleOrDefault 结合使用?
@erikkallen:不幸的是,LINQ 没有“MaxBy”-因此您无法获得具有最大值的行。对于 LINQ to Objects,您可以相当轻松地编写自己的代码,但我不确定在这种情况下是否有更好的方法。你会建议什么?
A
Adriaan Stander

看看这个

Understanding the 'using' statement in C#

CLR 将您的代码转换为 MSIL。并且 using 语句被转换为 try 和 finally 块。这就是使用语句在 IL 中的表示方式。 using 语句被翻译成三个部分:获取、使用和处置。首先获取资源,然后将使用情况包含在带有 finally 子句的 try 语句中。然后对象在 finally 子句中被释放。


一个有趣的见解。谢谢。
这将问题转化为:从 try-finally 的 try-block 返回的任何副作用?
不,finally 总是会被调用。 techinterviews.com/interview-questions-for-c-developers
M
Mitch Wheat

using() 语句内部返回有没有副作用。

它是否使代码最易读是另一个讨论。


K
Kerido

我想,都是一样的。代码中没有什么不好的。 .NET 框架不会关心对象是在哪里创建的。重要的是它是否被引用。


A
Alexandre

是的,可能会有副作用。例如,如果您在 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);
    }
}

如果你在 using 语句之外定义事务,你会得到同样的错误。在这种情况下,使用关键字是不相关的。