2009-08-03 3 views
8

Какой способ лучше использовать: вернуть значение из метода внутри оператора using или объявить переменную раньше, установить ее и вернуть ее после?Лучшая практика возврата от использования блоков

public int Foo() 
{ 
    using(..) 
    { 
    return bar; 
    } 
} 

или

public int Foo() 
{ 
    var b = null; 
    using(..) 
    { 
    b = bar; 
    } 
    return b; 
} 

ответ

9

Я предпочитаю первый пример. Меньшее число переменных, меньшее количество строк кода, легче следовать, проще в обслуживании ...

public int Foo() 
{ 
    using(..) 
    { 
    return bar; 
    } 
} 
2

Нет причин не так, что using оператор переводит в try...finally блок и finally часть гарантированно будет выполнена (даже через возвращение или необработанное исключение).

+1

Кто-то всегда должен указывать это - блок finally будет * не * «гарантирован» выполненным вообще. Есть четко определенные обстоятельства, при которых они будут выполняться, а другие - там, где это не будет. –

+1

Есть примеры, где этого не будет? –

+1

@Earwicker: если случаи, когда он не будет исполнен, составляют <0.01%, то я думаю, что для большинства целей мы можем сказать, что это «гарантировано». –

1

Это действительно подходит для личных предпочтений. Вы найдете аргументы по обеим сторонам этого конкретного забора. Сам я предпочитаю вариант 1: возвращение, как только сможете. Я считаю, что это лучше отражает смысл кода; нет оснований держаться дольше, чем нужно. Если вы завершили всю свою работу, вернитесь.

Иногда у вас будет несколько возможных точек возврата, а работа «end-of-method» (регистрация, очистка) может привести вас к одному оператору возврата. Ничего страшного в этом, но вы часто можете справиться с этими ситуациями в блоках finally или с аспектами в аспектно-ориентированном программировании.

+1

Я согласен с личными предпочтениями. Я предпочитаю делать возврат в конце/конце метода. Руководства по кодированию часто также диктуют это. Вероятно, это также связано с тем, что методы иногда слишком длинны, что приводит к нечитаемым методам. Держите их на самом деле короткими, и ваши методы читаются снова. Так что это один из ответов «это зависит», я думаю! ;) Глядя на них из лучших практик, афайк там действительно не один, это скорее вопрос предпочтения. –

5

Следуя принципу «меньше больше» (на самом деле только вариант KISS), первый. Существует меньше строк кода для поддержки, без изменений в семантике и без потери удобочитаемости (возможно, этот стиль легче читать).

5

От using Statement - MSDN

используя заявление гарантирует, что Dispose вызывается даже если исключение происходит в то время как вы вызываете методы на объекте. Вы можете достичь результата , поставив объект внутри блока try, а затем вызывая Утилизируйте в блок finally; на самом деле, так используется оператор using , переведенный компилятором.

От try-finally (C# Reference)

наконец используется, чтобы гарантировать операторный блок кода выполняет независимо от того, как вышел из предыдущего попытка блока.

Чтобы ответить на ваш вопрос, да, его нормально возвращать из используемого заявления.

+0

Он спросил, какая из вышеперечисленных является лучшей практикой, а не семантикой используемого оператора. Вероятно, семантика здесь важна, но она не отвечает на поставленный вопрос. – jason

+0

@Jason: достаточно справедливо .. Заголовок вопроса: «Можно ли вернуться из метода внутри используемого оператора?» .. вы могли видеть, что я не единственный, кто читал вопрос таким образом. –

+1

@Stan R: Я вижу потенциал для путаницы, но сообщение ясно спрашивает о лучших практиках, а не о том, будет ли выполняться блок finally (т. Е. Семантика). – jason

3

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

Сам оператор using не может иметь значение, которое является ограничением.Предположим, у вас есть метод, называемый Open, который возвращает открытый FileStream, и вы хотите, чтобы получить длину файла:

Console.WriteLine(Open().Length); 

Исправлена ​​ошибка есть, что вы не располагая FileStream. Таким образом, вы должны написать (аналогично ваш пример):

long length; 

using (FileStream file = Open()) 
    length = file.Length; 

Console.WriteLine(length); 

Но с simple extension method, вы можете написать вместо этого:

Console.WriteLine(Open().Use(file => file.Length)); 

Приятных и аккуратные, и FileStream получают должным образом утилизировать.

+0

Аккуратно, но не читается в то же время :-) –

+0

Хе-хе это довольно аккуратно. thx для умной идеи. –

+0

@Scott P - это по сути та же идея, что и '? : 'operator (« выражение », эквивалентное' if'). Некоторые находят '? : 'менее читаемый, чем эквивалентный оператор' if', я считаю, что он может быть понятнее иногда. Устранение имен переменных часто помогает с ясностью. –

1

Я чувствую второй один лучше

public int Foo() 
{ 
    using(..) 
    { 
    return bar; 
    } 
} 

Одна вещь, которая возникает в виду при использовании этого пути является то, что мы возвращаемся в между использованием так будет объект (который мы завернутые в использовании) получит расположенный , ответ yes , потому что оператор using - это просто смесь блока try/finally, также хорошо вернуться из блока try. Возвращаемое выражение будет оценено, тогда будет выполнен блок finally, и этот метод будет return then.So go Ahead :)

Смежные вопросы