C #: когда я должен использовать TryParse? - PullRequest
14 голосов
/ 15 марта 2010

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

Как бы то ни было, примеры, которые я видел, совпадают со строками блока if / else с TryParse, в противном случае возвращается сообщение об ошибке. И для меня это в основном то же самое, что использовать блок try / catch с catch, возвращающим сообщение об ошибке.

Итак, я что-то упустил? Есть ли ситуация, когда это действительно полезно?

Ответы [ 10 ]

23 голосов
/ 15 марта 2010

Помимо аспекта производительности, который вы упомянули сами, есть и семантическая разница:

Использование try / catch предназначено для исключительных обстоятельств. Ввод неверных данных - это то, что вы ожидаете, а не что-то исключительное.

12 голосов
/ 15 марта 2010

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

Почему вы не хотите исключения, если данные недействительны?

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

Это зависит от контекста, и выбор методов Parse и TryParse позволяет вам выбрать подходящий для вас механизм синтаксического анализа.

7 голосов
/ 15 марта 2010

Где возможно, используйте TryParse - использовать его намного дешевле, чем получить исключение.

2 голосов
/ 15 марта 2010

Предположим, вы читаете файл журнала:

public IEnumerable<LogEntry> GetAllValidEntries() {
    while (!logReader.Finished) {
        string nextLine = logReader.ReadLine();
        LogEntry nextEntry;

        if (TryParseLogEntry(nextLine, out nextEntry))
            yield return nextEntry;
    }
}

private bool TryParseLogEntry(string line, out LogEntry logEntry) {
    logEntry = null;

    if (string.IsNullOrEmpty(line))
        return false;

    string[] cells = line.Split(';');
    if (cells.Length < 3)
        return false;

    DateTime time;
    decimal price;
    int quantity;

    // We just want to read this line of text as a LogEntry
    // IF it is valid; otherwise, there's no reason to throw
    // an error in the user's face
    if (!DateTime.TryParse(cells[0], out time) ||
        !decimal.TryParse(cells[1], out price) ||
        !int.TryParse(cells[2], out quantity))
        return false;

    logEntry = new LogEntry(time, price, quantity);
    return true;
}

Так как вся цель приведенного выше кода состоит в извлечении допустимых элементов из последовательности (которая предположительно должна содержать некоторые недействительные элементы), я думаю, что TryParse методы создают лот * На 1008 * больше смысла в этом случае, чем Parse методов, которые требуют правильного ввода.

1 голос
/ 15 марта 2010

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

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

1 голос
/ 15 марта 2010

Если вам нужно установить значение по умолчанию при сбое анализа, попробуйте TryParse вместе с if.

0 голосов
/ 15 марта 2010

Если вы делаете проверку ввода в форме, вы можете установить ErrorProvider на элемент управления (или MessageBox, или какое-либо другое уведомление), когда он возвращает false. Это не исключительный случай, потому что, как говорили другие, вы должны планировать это.

0 голосов
/ 15 марта 2010

Я не обезьяна c #, но ...

Исключение прерывает нормальный поток кода, передавая обработку в блок catch.

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

0 голосов
/ 15 марта 2010

Каждый раз, когда вам нужно выполнить синтаксический анализ, так как его использование обходится дешевле, чем Исключение, плюс вы можете сделать его частью простого оператора if вместо большого блока try ... catch.

0 голосов
/ 15 марта 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...