Рефакторинг операторов if при изменении одного и того же значения в разных условиях - PullRequest
0 голосов
/ 21 мая 2018

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

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

Итак, мой вопрос, есть ли у кого-нибудь идея лучше в конечном итоге рефакторинг это?Есть ли какие-либо проблемы с выполнением этого в операторах if (с логической, чистой стороны кода и т. Д.).

Все мои методы имеют ключевое слово ref (для имени строковой переменной).Извините за путаницу!

 private string GenerateNameFrom(IRow row)
 {
    string name = string.Empty;

    if (Method1(name,row))
        return name;
    else if (Method2(name,row))
        return name;
    else if (Method3(name,row))
        return name;
    else return "Null";
}

Ответы [ 5 ]

0 голосов
/ 21 мая 2018

Я бы постарался не использовать ref в этом случае.Вместо этого вы можете сделать так, чтобы различные методы возвращали кортеж (bool success, string value) следующим образом:

public static (bool success, string value) Method1(string name)
{
    if (name == "test")
        return (true, "changed");

    return (false, null);
}

public static (bool success, string value) Method2(string name)
{
    if (name == "test")
        return (true, "changed");

    return (false, null);
}

public static (bool success, string value) Method3(string name)
{
    if (name == "test")
        return (true, "changed");

    return (false, null);
}

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

private string GenerateNameFrom(/*IRow row*/)
{
    string name = string.Empty;

    var result = Method1(name);

    if (result.success)
        return result.value;

    result = Method2(name);

    if (result.success)
        return result.value;

    result = Method3(name);

    if (result.success)
        return result.value;

    return null;
}

В качестве альтернативы, если null может использоваться для указания "нет результата", тогда просто сделайте то же самое, но проверьте возвращаемое значение дляnull:

private string GenerateNameFrom(/*IRow row*/)
{
    string name = string.Empty;

    var result = Method1(name);

    if (result != null)
        return result;

    result = Method2(name);

    if (result != null)
        return result;

    return Method3(name);
}

public static string Method1(string name)
{
    if (name == "test")
        return "changed";

    return null;
}

public static string Method2(string name)
{
    if (name == "test")
        return "changed";

    return null;
}

public static string Method3(string name)
{
    if (name == "test")
        return "changed";

    return null;
}
0 голосов
/ 21 мая 2018

Не вижу реализации ваших методов, но я предполагаю что-то вроде:

public bool Method1(ref string name)
{
    if (condition)
    {
        name = "SomeValue";
        return true;
    }

    return false;
}

Вы можете изменить эти методы для возврата обновленного имени:

public string Method1(name)
{
    if(condition)
    {
        return "SomeValue";
    }

    return null;
}

Итогда вы можете просто обнулить вызовы методов:

private string GenerateNameFrom(IRow row)
{
    string name = string.Empty;
    return Method1(name)
        ?? Method2(name)
        ?? Method3(name)
        ?? "Null";
}
0 голосов
/ 21 мая 2018

Хорошо, все это Method1(name) и Method2(name) выполняют некоторую проверку входной строки name и возвращают bool.В этом случае предлагается объединить всю логику проверки в одном методе, используя оператор switch, возможно, и использовать этот метод вместо

.
0 голосов
/ 21 мая 2018

Имя переменной всегда будет содержать пустую строку.как вы объявляете и инициализируете непосредственно перед оператором if

Любой как ниже краткий способ получить тот же результат.Результат будет таким же, как приведенный ниже код и ваш код:

if (Method1(name) || Method2(name) || Method3(name))
{
    return name;
}
else
{ 
    return "Null";
}

Или, более конкретно, с использованием троичного оператора

(Method1(name) || Method2(name) || Method3(name)) ? name : "Null";
0 голосов
/ 21 мая 2018

Вот один из способов сделать это:

private string GenerateNameFrom(IRow row)
{
    var name = "";
    return (Method1(ref name) || Method2(ref name) || Method3(ref name)) ? name : "Null";
}
  • Использование var для создания пустой строки, не нужно писать string дважды.
  • Использование || означает, что первый метод, который возвращает true, будет удовлетворять условию, и никакой другой метод не будет выполнен.
  • Использование ?: оператор условного возврата.

Примечание: Как прокомментировал Мэтью Уотсон, вы, вероятно, пропускаете ключевое слово ref (или out) - потому что даже при наличии строкиявляется ссылочным типом, он также неизменен, поэтому, если вы хотите, чтобы ваши методы влияли на содержимое аргумента name, вы должны либо отправить его как ref, либо как out, поскольку единственный способ изменить его значение - этоназначить ему новую строку.

(также преобразовал String.Empty в "", но это всего лишь личное предпочтение)

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