У Вас был бы к самокрутке "идентификационный тип" транзакции tx управления. Таким образом, это были бы 4 вызова:
http://service/transaction (some sort of tx request)
http://service/bankaccount/bob (give tx id)
http://service/bankaccount/john (give tx id)
http://service/transaction (request to commit)
необходимо было бы обработать хранение действий в DB (если сбалансированная загрузка) или в памяти или таком, то обработка фиксации, отката, тайм-аута.
Едва ли УСПОКОИТЕЛЬНЫЙ день в парке.
Этот метод пытается сделать три разные вещи:
Это довольно беспорядочно с точки зрения дизайна.
Лучшим подходом было бы просто объявить:
public static List<Poll> GetPolls()
Затем пусть этот метод генерирует исключение
, если что-то пойдет не так.
Также существует этот шаблон, который можно увидеть во многих функциях Win32.
public static bool GetPolls(out List<Poll> polls)
if(!PollStuff.GetPolls(out myPolls))
string errorMessage = PollStuff.GetLastError();
Но ИМО это ужасно. Я бы выбрал что-то, основанное на исключениях, если только этот метод не должен работать 65 раз в секунду в трехмерном игровом физическом движке или где-то еще.
Методы C # действительно должны делать только одно. С помощью этого метода вы пытаетесь сделать три вещи. Я бы поступил так, как предлагали другие, и выбросил бы исключение в случае ошибки. Другой вариант - создать методы расширения для вашего объекта List.
например, в общедоступном статическом классе:
public static List<Poll> Fill( this List<Poll> polls) {
// code to retrieve polls
}
Затем, чтобы вызвать это, вы должны сделать что-то вроде:
List<Poll> polls = new List<Poll>().Fill();
if(polls != null)
{
// no errors occur
}
edit: я только что придумал. вам может понадобиться новый оператор в List
Думаю, все в порядке. Я бы предпочел:
enum FailureReasons {}
public static IEnumerable<Poll> TryGetPolls(out FailureReasons reason)
Значит, строки ошибок не живут в коде доступа к данным ...
Я бы переформулировал это так.
public static List<Poll> GetPolls()
{
...
}
Вероятно, он должен генерировать исключение (сообщение errorMessage), если не удается получить результаты опросов, плюс это позволяет использовать цепочку методов, что менее громоздко чем иметь дело с параметрами out.
Если вы запустите FxCop, вы захотите изменить List на IList, чтобы он оставался довольным.
Это зависит от того, как часто метод дает сбой. Как правило, об ошибках в .Net следует сообщать с помощью исключения
. Случай, когда это правило не выполняется, - это частое условие ошибки, а влияние на производительность throw
и исключения слишком велико.
Для работы с типом базы данных я думаю, что существует Exception
лучше всего.
Зависит от того, является ли ошибка обычным явлением или действительно является исключением.
Нет, с моей точки зрения, это очень плохой стиль. Я бы написал это так:
public static List<Poll> GetPolls();
Если вызов завершился неудачно, выбросить исключение и поместить сообщение об ошибке в исключение. Для этого нужны исключения, и ваш код станет намного чище, читабельнее и проще в обслуживании.
Пожалуйста, сформулируйте свои предположения, ограничения, желания / цели и доводы; мы должны угадывать и / или читать ваши мысли, чтобы узнать, каковы ваши намерения.
предполагая, что вы хотите, чтобы ваша функция
, тогда указанная выше сигнатура подходит (хотя проглатывание всех возможных исключений не является хорошей практикой).
Как общий стиль кодирования, он имеет некоторые потенциальные проблемы, так как другие упомянули.
Подумайте о возврате:
Несколько выходных параметров для меня - это запах кода . Этот метод должен выполнять только ОДНУ ВЕЩЬ.
Рассмотрите возможность создания и обработки сообщений об ошибках с помощью:
throw new Exception("Something bad happened");
//OR
throw new SomethingBadHappenedException();
Как правило, я бы сказал «нет».
Я говорю «нет» на самом деле не потому, что вы выполняете TryGetX
и возвращаете bool
с параметром out
. Я считаю, что это плохой стиль, потому что вы также возвращаете строку с ошибкой.
Try
должен игнорировать только одну конкретную, часто встречающуюся ошибку. Другие проблемы могут вызывать исключение с соответствующим сообщением об исключении. Помните, что цель такого метода Try
- избежать накладных расходов, связанных с созданным исключением, когда вы ожидаете, что конкретный, единственный вид сбоя будет происходить чаще, чем нет.
Вместо этого, что вы ' Мы ищем пару методов:
public static bool TryGetPolls( out List<Poll> polls );
public static List<Poll> GetPolls();
Таким образом, пользователь может делать то, что ' уместно, и GetPolls
могут быть реализованы в терминах TryGetPolls
. Я предполагаю, что ваша статичность
имеет смысл в контексте.
Думаю,
public static bool TryGetPolls(out List<Poll> polls)
было бы более подходящим. Если это метод TryGet
, то мое первоначальное предположение будет заключаться в том, что есть основания ожидать, что он потерпит неудачу, и ответственность за определение того, что делать дальше, лежит на вызывающей стороне. Если вызывающий абонент не обрабатывает ошибку или хочет получить информацию об ошибке, я ожидаю, что они вызовут соответствующий метод Get
.
Это определенно не идиоматический способ написания C #, что также означает, что это, вероятно, тоже не лучший стиль.
Когда у вас есть TryGetPolls
то это означает, что вам нужны результаты, если операция завершилась успешно, а если нет, то вам все равно, почему она не удалась.
Если у вас есть просто метод GetPolls
, тогда он означает, что вам всегда нужны результаты, и если это не удается, вы хотите знать, почему, в виде Exception
.
Смешивание этих двух значений находится где-то посередине, что будет необычно для большинства люди. Поэтому я бы сказал, либо не возвращать сообщение об ошибке, либо генерировать исключение
в случае сбоя, но не используйте этот странный гибридный подход.
Таким образом, сигнатуры ваших методов, вероятно, должны быть либо:
Это зависит от сообщения об ошибке. Например, если обработка не может быть продолжена из-за недоступности подключения к базе данных и т. Д., Тогда вы должны выбросить исключение, как упоминали другие люди.
Однако может оказаться, что вы просто хотите вернуть «мета» информацию о попытке, и в этом случае вам просто нужен способ вернуть более одной части информации из одного вызова метода. В этом случае я предлагаю создать класс PollResponse, содержащий два свойства: List
class PollResponse
{
public List<Poll> Polls { get; }
public string MetaInformation { get; }
}
Не совсем - я вижу ряд проблем с этим.
Во-первых, метод звучит так, как будто обычно он будет успешным; ошибки (невозможно подключиться к базе данных, нет доступа к таблице polls
и т.д.) будут редкими. В этом случае гораздо разумнее использовать исключения для сообщения об ошибках. Попробуйте ...
шаблон предназначен для случаев, когда вы часто ожидаете, что вызов «потерпит неудачу» - например, при синтаксическом разборе строки до целого числа велики шансы, что строка является пользовательским вводом, который может быть недопустимым, поэтому вам нужен быстрый способ справиться с этим - отсюда TryParse
. Здесь дело обстоит не так.
Во-вторых, вы сообщаете об ошибках в виде значения bool
, указывающего на наличие или отсутствие ошибки, и в виде строкового сообщения. Как тогда вызывающий абонент будет различать различные ошибки? Он определенно не может сопоставить текст сообщения об ошибке - это деталь реализации, которая может быть изменена и может быть локализована. И может быть огромная разница между чем-то вроде «Не удается подключиться к базе данных» (может быть, просто откройте диалоговое окно настроек подключения к базе данных в этом случае и разрешите пользователю редактировать его?) И «Подключено к базе данных, но там написано« Доступ запрещен » ". Ваш API не дает хорошего способа различить их.
Подводя итог: используйте исключения вместо bool
+ out string
для сообщения сообщений. Как только вы это сделаете, вы можете просто использовать List
в качестве возвращаемого значения без необходимости в аргументе out
. И, конечно же, переименуйте метод в GetPolls
, с Попробуйте ...
зарезервирован для шаблона bool + out
.
В руководстве говорится, что нужно избегать параметров ref и out , если они не являются абсолютно необходимыми, поскольку они затрудняют использование API (нет больше цепочек методов, разработчик должен объявить все переменные перед вызовом метода)
Также не рекомендуется возвращать коды ошибок или сообщения, лучше всего использовать исключения и обработку исключений для создание отчетов об ошибках, иначе ошибки станут легко игнорировать, и потребуется больше работы по передаче информации об ошибках, в то же время потеря ценной информации, такой как трассировка стека или внутренние исключения.
Лучший способ объявить метод - вот такой.
public static List<Poll> GetPolls() ...
и для отчетов об ошибках используйте обработку исключений
try
{
var pols = GetPols();
...
} catch (DbException ex) {
... // handle exception providing info to the user or logging it.
}
Я что-то упустил? Задающий вопрос, похоже, хочет знать, как очистить ресурсы, если метод не работает.
public static IList<Poll> GetPolls()
{
try
{
}
finally
{
// check that the connection happened before exception was thrown
// dispose if necessary
// the exception will still be presented to the caller
// and the program has been set back into a stable state
}
}
С точки зрения дизайна, я бы подумал о том, чтобы поместить этот метод в класс хранилища, чтобы у вас был какой-то контекст, с помощью которого можно было бы понять метод. Все приложение, предположительно, не отвечает за хранение и получение опросов: за это должно отвечать хранилище данных.