который лучше, с помощью nullable или булевской переменной return+out параметр

Для векторов этот поток на форумах MSDN имеет фрагмент кода для установки часов на векторном индексе, который мог бы помочь.

6
задан Oren Mazor 25 November 2009 в 21:22
поделиться

11 ответов

Мне больше нравится версия с нулевым значением, потому что вы можете использовать нулевой оператор объединения ?? на нем, например:

int reallyTerrible = 0;
var mightBeWonderful = DoSomethingWonderful() ?? reallyTerrible;
12
ответ дан 8 December 2019 в 03:27
поделиться

Это зависит от того, как, по вашему мнению, должен выглядеть вызывающий код. И поэтому для чего используется ваша функция.

Как правило, вам следует избегать аргументов out. С другой стороны, было бы неплохо иметь такой код:

int parameter;
if (DoSomething(out paramameter))
{
  // use parameter
}

Когда у вас есть int, допускающий значение NULL, это будет выглядеть так:

int? result = DoSomething();
if (result != null)
{
  // use result
}

Это несколько лучше, потому что у вас нет аргумента out, но Код, который определяет, удалось ли выполнить функцию, выглядит не очень очевидным.

Не забывайте, что есть еще один вариант: использовать Exeptions. Делайте это только в том случае, если случай, когда ваша функция не работает, действительно является исключительным и своего рода случаем ошибки.

try
{
  // normal case
  int result = DoSomething()
}
catch (SomethingFailedException ex)
{
  // exceptional case
}

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

Изменить: Забыл упомянуть: еще одно преимущество исключения состоит в том, что вы также можете предоставить информацию , почему операция не удалась. Эта информация предоставляется типом исключения, свойствами исключения и текстом сообщения.

5
ответ дан 8 December 2019 в 03:27
поделиться

Почему бы не создать исключение?

3
ответ дан 8 December 2019 в 03:27
поделиться

Я бы следовал шаблону, используемому в каком-то месте библиотеки .Net, например:

bool int.TryParse(string s, out value)
bool Dictionary.TryGetValue(T1 key, out T2 value)

Итак, я бы сказал:

public bool TryDoSomethingWonderful(out int parameter)
2
ответ дан 8 December 2019 в 03:27
поделиться

Это действительно зависит от того, что вы делаете.

Является ли значение null значимым ответом? Если нет, я бы предпочел вызов метода bool TryDoSomethingWonderful (out int) . Это соответствует Framework.

Если, однако, null является значимым возвращаемым значением, возвращая int? имеет смысл.

2
ответ дан 8 December 2019 в 03:27
поделиться

Я бы использовал второй, потому что мне, вероятно, нужно сразу узнать, был ли вызов успешным, и в этом случае я лучше напишу

int x;
if( DoSomethingWonderful( out x ) )
{
    SomethingElse(x);
}

, чем

int? x = DoSomethingWonderful();
if( x.HasValue )
{
   SomethingElse(x.Value);
}
2
ответ дан 8 December 2019 в 03:27
поделиться

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

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

0
ответ дан 8 December 2019 в 03:27
поделиться

Интересно, что мое личное мнение существенно меняется в зависимости от характера метода. В частности, если цель метода - получить одно значение , в отличие от «делать что-то».

Пример:

bool GetSerialNumber(out string serialNumber)

vs

string GetSerialNumber() // returns null on failure

Второе кажется мне более «естественным», и аналогично:

bool GetDeviceId(out int id)

vs

int? GetDeviceId() // returns null on failure`

Но я признаю, что это действительно относится к сфере "стиля кодирования".

О, и я тоже склонен предпочитать выбросы исключений:

int GetDeviceId() // throws an exception on read failure

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

0
ответ дан 8 December 2019 в 03:27
поделиться

Лучше, чем использовать try catch. Похоже, вызывающий не знает, что может случиться?

Должны ли мы проверять и bool, и out, или я должен проверять и возвращающий null, и фактический return.

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

0
ответ дан 8 December 2019 в 03:27
поделиться

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

2
ответ дан 8 December 2019 в 03:27
поделиться

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

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

        int value;
        if(DoSomethingWonderful(out value))
        {
            // continue on your merry way
        }
        else
        {
            // oops
            Log("Unable to do something wonderful");

            if (DoSomethingTerrible(out value))
            {
                // continue on your not-so-merry way
            }
            else
            {
                GiveUp();
            }
        }

Кроме того, если значение, которое я хочу получить, действительно допускает значение NULL , то использование функции с выходным параметром и логическим возвращаемым значением, на мой взгляд, является самым простым способом определить разницу между «Мне не удалось получить значение» и «Полученное мной значение равно нулю». Иногда меня волнует это различие, например, в следующем примере:

    private int? _Value;
    private bool _ValueCanBeUsed = false;

    public int? Value
    {
        get { return this._Value; }
        set
        {
            this._Value = value;
            this._ValueCanBeUsed = true;
        }
    }

    public bool DoSomethingTerrible(out int? value)
    {
        if (this._ValueCanBeUsed)
        {
            value = this._Value;
            // prevent others from using this value until it has been set again
            this._ValueCanBeUsed = false;
            return true;
        }
        else
        {
            value = null;
            return false;
        }
    }

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

1
ответ дан 8 December 2019 в 03:27
поделиться
Другие вопросы по тегам:

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