Стоит ли использовать кортежи значений в качестве возвращаемого значения, чтобы включить флаг успеха?

Я ищу альтернативы возвращению нулевого значения. До С# 7 общая картина была

public bool TryParseInt(string data, out int result);

Но теперь мы можем также использовать кортеж значения и деконструкторы для чего-то вроде этого

public (bool parsed, int result) TryParseInt(string data){}

var (parsed, result) = TryParseInt("0");
if(parsed == false)
      return;

Стоит ли писать такие функции? Я сильно не люблю все, что "вне", потому что это может быть легко пропущено при поиске ошибок.

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

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

Ответ 1

Спросите себя: "Могу ли я сделать что-то подобное?"

public Tuple<bool, int> TryParseInt(string data)
{
   ...
}

Если ответ "да", тогда используйте ValueTuples:

public (bool parsed, int result) TryParseInt

Насколько я помню, стандартные соглашения о кодировании говорят что-то вроде:

Если имя метода начинается со слова "Try", ожидается, что он вернет либо обнуляемый тип, либо параметр bool + out.

Вот два варианта, которые у нас есть:

public int? TryParseInt(string data) // or
public bool TryParseInt(string data, out int number)

Я бы использовал первый вариант и возвращал null в случае сбоя операции синтаксического анализа.

int? parsed = TryParseInt("1");

if(parsed != null)
{
   // ... do something with parsed.Value;
}

Или, как любезно предложено Ghost4Man, вы можете сделать его немного более читабельным:

if(TryParseInt("1") is int number)
{
   // do something with number
}

Ответ 2

Я думаю, что это основано на мнении. Как сказано, выбирай что хочешь больше :)

Но для случая использования предоставленных вами, я рекомендую использовать out параметров и первый шаблон, так что вы можете писать чистый код, такие как:

if(TryParseInt("123", out int parsed))
{
  //use parsed variable
}

или же

var i = TryParseInt("123", out int parsed) ? parsed : -1; // -1 is just example

С кортежами этот код станет менее читабельным ИМХО.