Когда предполагается использовать «Try» в именах методов C #?


180

Мы обсуждали с нашими коллегами, что означает, если имя метода начинается с «Try».

Были следующие мнения:

  • Используйте «Try», когда метод может вернуть нулевое значение.
  • Используйте «Try», когда метод не сгенерирует исключение.

Какое официальное определение? Что говорит «Try» в названии метода? Есть ли официальное руководство по этому поводу?


83
+1 Люди, которые так много думают об именах своих функций, на самом деле ищут «следующего парня». Не уверенный, почему это получает близкие голоса (и это от парня, который бросил много из них сегодня вечером.)
Джонатон Рейнхарт

7
@JonathonReinhart, он получил близкие голоса, потому что «В настоящее время этот вопрос не подходит для нашего формата вопросов и ответов. Мы ожидаем, что ответы будут подкреплены фактами, ссылками или конкретными знаниями, но этот вопрос, скорее всего, вызовет дебаты, аргументы , опрос или расширенное обсуждение. "
Пранав Хосангади

16
Там является официальное заявление Microsoft , что отвечает на вопрос (см мой ответ). Как это не факт?
Эрик Скьербум

6
@PranavHosangadi, как упоминал Эрик, подтверждается фактами. Кроме того, здесь есть много очень опытных разработчиков на C #, которые имеют определенный опыт, чтобы дать правильный ответ. Черт, Эрик Липперт - главный архитектор языка C #. Я думаю, что вы можете назвать эту конкретную экспертизу .
Джонатон Рейнхарт

4
@ErikSchierboom То, что это руководство MS - факт. То, что руководство MS является правильным руководством, является субъективным и спорным.
Обслуживание

Ответы:


148

Это известно как шаблон TryParse и было задокументировано Microsoft. В официальных Исключения и производительность MSDN страница говорит :

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

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


2
Еще одна полезная ссылка, которая документирует этот шаблон (поиск TryParse) blogs.msdn.com/b/kcwalina/archive/2005/03/16/396787.aspx
Вивек Махарадж,

2
По сути, если у вас есть метод TryParse, у вас должен быть метод Parse, который выдает, когда TryParse возвращает false. И наоборот, если у вас есть метод Parse, вы должны рассмотреть возможность использования метода TryParse, который возвращает false при
выдаче

5
+1. Просто чтобы добавить к этому, исключения, как правило, для «исключительных» обстоятельств. Если вы делаете что-то, что может легко потерпеть неудачу, и эта неудача не особенно заметна, то использование этого паттерна более идиоматично, чем попытка-поймать
Адам Робинсон,

Действительно ли такой шаблон требовал рекомендаций от Microsoft? Кажется довольно простой материал.
Дейв Лоуренс

19
Это является основным материалом, но это вовсе не означает , что рекомендации не являются полезными. Правильно понять основные вещи может быть довольно сложно, если вы недостаточно хорошо знаете платформу.
Эрик Скьербум

119

(Исправлено) Существует официальное руководство, как предложил Эрик.

Когда я вижу TrySomethingметод, я предполагаю это

  • не бросает
  • возвращается bool
  • если я ожидаю значение, оно возвращается через параметр «out»
  • Существует Somethingметод, который позволяет мне обрабатывать любые исключения самостоятельно. (редактировать, предложенный Джесси Уэббом)

4
Исправление - имеет официальное руководство. Смотрите ответ Эрика.
nothrow

8
+1 Но у меня также есть 4-е ожидание: если есть TryFooметод, будет аналогичный Fooметод, который позволит мне обрабатывать любые `` исключения самостоятельно. Сигнатуры этих методов, вероятно, будут другими, поэтому их использование не будет взаимозаменяемым без других изменений кода.
Джесси Уэбб

1
@JesseWebb, спасибо за указание на это. Я добавил ваш комментарий в мой ответ, если вы не возражаете.
nothrow

1
«Не бросает» кажется мне чрезмерно обобщенным. Например, Int32.TryParse (String, NumberStyles, IFormatProvider, Int32) выдает исключение ArgumentException, если ему не нравится параметр стиля.
Йирка Ханика,

Я согласен, что «не выбрасывает» можно считать чрезмерно обобщенным, но я считаю, что цель состояла в том, чтобы передать, что он не выбрасывает в результате выполнения, а не в результате значения параметров.
ConfusingBoat

8

Я думаю, что вы должны использовать, tryкогда вы хотите продолжить. Неважно, что метод возвращает какое-то значение или нет.

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

Случай 2: если он не возвращается: он все еще в порядке; Вы можете продолжить как-то иначе.

И если вы ожидаете какое-то значение в качестве вывода этого метода, используйте outпараметр.

пример

int value
if (dictionary.TryGetValue("key", out value))
{
    // Proceed in some way
}
else
{
    // Proceed in some other way
}

6

Вы должны использовать «Try» в имени метода, когда вы хотите продемонстрировать тот факт, что вызов метода может привести к неверному результату. Следуя стандарту .NET, это, кстати, не функция, которая вызывает исключение, а функция, которая возвращает некоторое VALIDили NON_VALID, с точки зрения программы, значение.

В конце концов, это все о соглашении об именах, которое вы решили использовать в своей группе.


5

Не забудьте включить tryв ваше имя метода, если:

  • ты не бросаешь никаких исключений
  • Ваш метод имеет следующую подпись: bool TrySomething(input, out yourReturn)

Таким образом, в основном, если мы используем try-методы, мы получаем только логический результат.

Поэтому следующий код не будет выдавать никаких исключений:

string input = "blabla";
int number;
if (int.TryParse(input, out number))
{
// wooohooo we got an int!
} else
{
//dooh!
}

Принимая во внимание, что этот код может (и в этом случае будет) генерировать исключения:

string input = "blabla";
int number;
try
{
     number = int.Parse(input); //throws an exception
}
catch (Exception)
{
     //dooh!
}

Использование методов Try - более безопасный и более безопасный способ написания кода. Также фрагмент кода № 2 требует большей производительности для выполнения, если это не целое число.


Ваш фрагмент кода № 2 должен быть прочитан, int number = int.Parse(input);если вы хотите, чтобы он был более значимым в этом контексте.
Пьер Арно

@PierreArnaud Спасибо, изменил это!
Фабиан Биглер

Вы все еще пропускаете int number;объявление перед блоком try и number = ...присваиванием.
Пьер Арно

@PierreArnaud Спасибо, я также добавил 'int number'.
Фабиан Биглер

Обратите внимание, что вы все равно можете выбросить исключения, если исключение несколько не связано с выполнением прямого действия, например, TryLoadFile(path, out file)вау, из ОЗУ. Таким образом, вызывающая сторона не будет ожидать ошибок при неверном пути или отказе в доступе, но будет исключением из более странных вещей, которые также могут пойти не так. И документируйте это.
Люк Пуплетт

0

Дядя Боб приводит пример ниже в своей книге « Чистый код» . Всякий раз, когда мы ожидаем, что будет сгенерировано исключение, мы можем использовать Tryпрефикс для имени метода:

public void sendShutDown()
{
    try{
        tryToShutDown();
    } catch (DeviceShutDownError e) {
        logger.log(e);            
    }
}

А потом (адаптировано):

private void tryToShutDown()
{
    //some code with no error handling, but
    //something might go wrong here
}

tryToShutDownМетод не делает никакой обработки ошибок, потому что это ответственность sendShutDownметоды.

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

Если мы не разрабатываем новую версию C #, нам не нужно следовать всем рекомендациям Microsoft. Иногда они не самые лучшие.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.