Этот хороший стиль C#?

У Вас был бы к самокрутке "идентификационный тип" транзакции 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 (если сбалансированная загрузка) или в памяти или таком, то обработка фиксации, отката, тайм-аута.

Едва ли УСПОКОИТЕЛЬНЫЙ день в парке.

10
задан Jon Seigel 4 April 2010 в 15:46
поделиться

17 ответов

Этот метод пытается сделать три разные вещи:

  1. Получить и вернуть список опросов
  2. Вернуть логическое значение, указывающее на успех
  3. Вернуть сообщение об ошибке

Это довольно беспорядочно с точки зрения дизайна.

Лучшим подходом было бы просто объявить:

public static List<Poll> GetPolls()

Затем пусть этот метод генерирует исключение , если что-то пойдет не так.

43
ответ дан 3 December 2019 в 13:11
поделиться

Также существует этот шаблон, который можно увидеть во многих функциях Win32.

public static bool GetPolls(out List<Poll> polls)


if(!PollStuff.GetPolls(out myPolls))
  string errorMessage = PollStuff.GetLastError();

Но ИМО это ужасно. Я бы выбрал что-то, основанное на исключениях, если только этот метод не должен работать 65 раз в секунду в трехмерном игровом физическом движке или где-то еще.

0
ответ дан 3 December 2019 в 13:11
поделиться

Методы 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 () .Fill ()

0
ответ дан 3 December 2019 в 13:11
поделиться

Думаю, все в порядке. Я бы предпочел:

enum FailureReasons {}
public static IEnumerable<Poll> TryGetPolls(out FailureReasons reason)

Значит, строки ошибок не живут в коде доступа к данным ...

0
ответ дан 3 December 2019 в 13:11
поделиться

Я бы переформулировал это так.

public static List<Poll> GetPolls()
{
    ...
}

Вероятно, он должен генерировать исключение (сообщение errorMessage), если не удается получить результаты опросов, плюс это позволяет использовать цепочку методов, что менее громоздко чем иметь дело с параметрами out.

Если вы запустите FxCop, вы захотите изменить List на IList, чтобы он оставался довольным.

0
ответ дан 3 December 2019 в 13:11
поделиться

Это зависит от того, как часто метод дает сбой. Как правило, об ошибках в .Net следует сообщать с помощью исключения . Случай, когда это правило не выполняется, - это частое условие ошибки, а влияние на производительность throw и исключения слишком велико.

Для работы с типом базы данных я думаю, что существует Exception лучше всего.

0
ответ дан 3 December 2019 в 13:11
поделиться

Зависит от того, является ли ошибка обычным явлением или действительно является исключением.

0
ответ дан 3 December 2019 в 13:11
поделиться

Нет, с моей точки зрения, это очень плохой стиль. Я бы написал это так:

public static List<Poll> GetPolls();

Если вызов завершился неудачно, выбросить исключение и поместить сообщение об ошибке в исключение. Для этого нужны исключения, и ваш код станет намного чище, читабельнее и проще в обслуживании.

2
ответ дан 3 December 2019 в 13:11
поделиться

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

предполагая, что вы хотите, чтобы ваша функция

  • создавала объект списка опросов
  • подавляла все исключения
  • указывала на успех с помощью boolean
  • и предоставить необязательное сообщение об ошибке при сбое

, тогда указанная выше сигнатура подходит (хотя проглатывание всех возможных исключений не является хорошей практикой).

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

0
ответ дан 3 December 2019 в 13:11
поделиться

Подумайте о возврате:

  • пустой коллекции
  • null

Несколько выходных параметров для меня - это запах кода . Этот метод должен выполнять только ОДНУ ВЕЩЬ.

Рассмотрите возможность создания и обработки сообщений об ошибках с помощью:

throw new Exception("Something bad happened");
//OR
throw new SomethingBadHappenedException();
7
ответ дан 3 December 2019 в 13:11
поделиться

Как правило, я бы сказал «нет».

Я говорю «нет» на самом деле не потому, что вы выполняете TryGetX и возвращаете bool с параметром out . Я считаю, что это плохой стиль, потому что вы также возвращаете строку с ошибкой.

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

Вместо этого, что вы ' Мы ищем пару методов:

public static bool TryGetPolls( out List<Poll> polls );
public static List<Poll> GetPolls();

Таким образом, пользователь может делать то, что ' уместно, и GetPolls могут быть реализованы в терминах TryGetPolls . Я предполагаю, что ваша статичность имеет смысл в контексте.

7
ответ дан 3 December 2019 в 13:11
поделиться

Думаю,

public static bool TryGetPolls(out List<Poll> polls)

было бы более подходящим. Если это метод TryGet , то мое первоначальное предположение будет заключаться в том, что есть основания ожидать, что он потерпит неудачу, и ответственность за определение того, что делать дальше, лежит на вызывающей стороне. Если вызывающий абонент не обрабатывает ошибку или хочет получить информацию об ошибке, я ожидаю, что они вызовут соответствующий метод Get .

11
ответ дан 3 December 2019 в 13:11
поделиться

Это определенно не идиоматический способ написания C #, что также означает, что это, вероятно, тоже не лучший стиль.

Когда у вас есть TryGetPolls то это означает, что вам нужны результаты, если операция завершилась успешно, а если нет, то вам все равно, почему она не удалась.

Если у вас есть просто метод GetPolls , тогда он означает, что вам всегда нужны результаты, и если это не удается, вы хотите знать, почему, в виде Exception .

Смешивание этих двух значений находится где-то посередине, что будет необычно для большинства люди. Поэтому я бы сказал, либо не возвращать сообщение об ошибке, либо генерировать исключение в случае сбоя, но не используйте этот странный гибридный подход.

Таким образом, сигнатуры ваших методов, вероятно, должны быть либо:

11
ответ дан 3 December 2019 в 13:11
поделиться

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

Однако может оказаться, что вы просто хотите вернуть «мета» информацию о попытке, и в этом случае вам просто нужен способ вернуть более одной части информации из одного вызова метода. В этом случае я предлагаю создать класс PollResponse, содержащий два свойства: List Опросы и строку ErrorMessage. Затем попросите ваш метод вернуть объект PollResponse:

class PollResponse
{
    public List<Poll> Polls { get; }
    public string MetaInformation { get; }
}
1
ответ дан 3 December 2019 в 13:11
поделиться

Не совсем - я вижу ряд проблем с этим.

Во-первых, метод звучит так, как будто обычно он будет успешным; ошибки (невозможно подключиться к базе данных, нет доступа к таблице polls и т.д.) будут редкими. В этом случае гораздо разумнее использовать исключения для сообщения об ошибках. Попробуйте ... шаблон предназначен для случаев, когда вы часто ожидаете, что вызов «потерпит неудачу» - например, при синтаксическом разборе строки до целого числа велики шансы, что строка является пользовательским вводом, который может быть недопустимым, поэтому вам нужен быстрый способ справиться с этим - отсюда TryParse . Здесь дело обстоит не так.

Во-вторых, вы сообщаете об ошибках в виде значения bool , указывающего на наличие или отсутствие ошибки, и в виде строкового сообщения. Как тогда вызывающий абонент будет различать различные ошибки? Он определенно не может сопоставить текст сообщения об ошибке - это деталь реализации, которая может быть изменена и может быть локализована. И может быть огромная разница между чем-то вроде «Не удается подключиться к базе данных» (может быть, просто откройте диалоговое окно настроек подключения к базе данных в этом случае и разрешите пользователю редактировать его?) И «Подключено к базе данных, но там написано« Доступ запрещен » ". Ваш API не дает хорошего способа различить их.

Подводя итог: используйте исключения вместо bool + out string для сообщения сообщений. Как только вы это сделаете, вы можете просто использовать List в качестве возвращаемого значения без необходимости в аргументе out . И, конечно же, переименуйте метод в GetPolls , с Попробуйте ... зарезервирован для шаблона bool + out .

1
ответ дан 3 December 2019 в 13:11
поделиться

В руководстве говорится, что нужно избегать параметров 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.
}
1
ответ дан 3 December 2019 в 13:11
поделиться

Я что-то упустил? Задающий вопрос, похоже, хочет знать, как очистить ресурсы, если метод не работает.

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
    }
}

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

0
ответ дан 3 December 2019 в 13:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: