Есть ли побочные эффекты возврата изнутри оператора using ()? - PullRequest
115 голосов
/ 03 марта 2010

Возвращая значение метода из внутри оператор использования, который получает 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;
    }
}

Но я всегда чувствую, что должен закрыть что-то , прежде чем я выйду из скобок, например. определив транзакцию перед оператором использования, получите ее значение внутри в скобках, а затем верните после скобок.

Будет ли определение и возврат переменной вне скобок лучше использовать или каким-либо образом сохранить ресурсы?

Ответы [ 5 ]

153 голосов
/ 03 марта 2010

Нет, мне кажется, так понятнее. Не волнуйтесь, 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);
    }
}
29 голосов
/ 03 марта 2010

Посмотрите на это

Понимание оператора using в C #

CLR преобразует ваш код в MSIL. И оператор использования получает переведен в попытке и, наконец, блок. Вот как оператор использования представлен в IL. Использование заявление переводится на три части: приобретение, использование и удаление. Ресурс первый приобрел, то использование приложено в заявлении попробовать с наконец пункт. Затем объект удаляется в последнем предложении.

4 голосов
/ 03 марта 2010

Есть нет побочных эффектов возврата изнутри оператора using().

Вопрос о том, делает ли он наиболее читаемый код, является другим обсуждением.

0 голосов
/ 11 декабря 2014

Да, может быть побочный эффект. Например, если вы используете ту же технику в методе действия ASP.NET MVC, вы получите следующую ошибку: «Экземпляр 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);
    }
}
0 голосов
/ 03 марта 2010

Я думаю, это все то же самое. В коде нет ничего плохого. .NET Framework не будет заботиться о том, где создается объект. Важно то, на что на него ссылаются или нет.

...