Должны ли проходить одноразовые предметы?
В обзоре кода сотрудник изменил мой код для передачи в потоке в качестве параметра. Он сказал, что это должно гарантировать, что ответственность за распоряжение объектом понятна вызывающей стороне. В некотором смысле я могу сопереживать. Я бы предпочел, чтобы создатель объекта также отвечал за очистку.
С другой стороны, ни один из методов не делает необходимость в using
более ясной. Я предпочитаю также более простой вызов метода.
Принять
public static TextReader Serialize<T>(T obj) where T: new()
{
if (obj == null) throw new ArgumentNullException("obj");
return Serialize<T>(obj, null);
}
VS
public static void Serialize<T>(T obj, TextWriter outbound) where T : new()
{
if (obj == null) throw new ArgumentNullException("obj");
Serialize<T>(obj, outbound, null);
}
Есть ли какая-либо техническая причина для добавления дополнительного параметра?
Ответы
Ответ 1
Это зависит от вашей архитектуры кода.
Я лично, как и второй подход (даже если он добавляет еще один аргумент), где определение функции утверждает, что оно не будет закрывать/удалять поток, но оно до Caller.
Это очень полезно в том случае, если вы собираетесь вызывать одни и те же функции в одном потоке, вы можете предположить, что каждый вызов функции закроется и снова откроет поток, это станет ресурсоемкой работой.
Ответ 2
Возможно, у вас уже есть TextWriter. Вот почему я предпочел бы вторую версию. Кроме того, он уменьшает объем действия метода Serialize: он сериализуется, но он ничего не открывает. Открытие - другая проблема.
Ответ 3
По мере развития проекта программист (программисты), поддерживающие код в первом, может не помнить, что ответственность за вызов для ограничения потока (особенно в нетривиальных случаях) является обязанностью вызывающего кода. Звонящие должны будут полагаться на документацию для правильной работы, и все читают документацию, не так ли?;)
второй подход "балансирует" ресурсы. Это делает его намного яснее, где лежит разделение обязанностей.
Ответ 4
Перегруженный метод Serialize-T СОЗДАЕТ поток? Если это случай, я предпочитаю # 1, потому что он упрощает "использование":
using (var stream = Serialize(a_T)))
{
// Do something else with the stream?
}
С другой стороны, может быть лучше, если вызывающий должен ПОСТАВИТЬ поток, и в этом случае вы хотели бы передать один из параметров a la.