Используйте нулевой условный оператор, чтобы установить значение 0, если ноль

Я новичок в C#, но не для программирования в целом. Я пытаюсь установить добавить некоторые проверки ошибок в моей программе. Есть 3 текстовых поля, и я пытаюсь сделать так, чтобы, если текстовое поле оставлено пустым, оно принимало значение 0. Вот мой код:

    private void btnCalculate_Click(object sender, EventArgs e)
    {
        if (String.IsNullOrEmpty(txtNumberOfClassATix.Text))    // Assumes 0 if no number entered for txtNumberOfClassATix.Text.
        {
            txtNumberOfClassATix.Text = "0";
        }
        if (String.IsNullOrEmpty(txtNumberOfClassBTix.Text))    // Assumes 0 if no number entered for txtNumberOfClassBTix.Text.
        {
            txtNumberOfClassBTix.Text = "0";
        }
        if (String.IsNullOrEmpty(txtNumberOfClassCTix.Text))    // Assumes 0 if no number entered for txtNumberOfClassCTix.Text.
        {
            txtNumberOfClassCTix.Text = "0";
        }
        int classANum = int.Parse(txtNumberOfClassATix.Text);
        int classBNum = int.Parse(txtNumberOfClassBTix.Text);
        int classCNum = int.Parse(txtNumberOfClassCTix.Text);
        double classATotal = classANum * classAPrice;
        double classBTotal = classBNum * classBPrice;
        double classCTotal = classCNum * classCPrice;
        lblCalculatedClassARevenue.Text = $"{classATotal:c}";
        lblCalculatedClassBRevenue.Text = $"{classBTotal:c}";
        lblCalculatedClassCRevenue.Text = $"{classCTotal:c}";
        lblCalculatedTotalRevenue.Text = $"{(classATotal + classBTotal) + classCTotal:c}";
    }

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

4 ответа

Пока что ответ Макчеттуры самый лучший, но можем ли мы сделать лучше? Мы можем точно. Давайте сделаем метод расширения общего назначения:

internal static class Extensions 
{
  public static int? AsInt(this string s)
  {
    int result;
    if (s == null)
      return null;
    else if (int.TryParse(s, out result))
      return result;
    else
      return null;
  }
}

И сейчас:

    int classANum = txtNumberOfClassATix.Text.AsInt() ?? 0;

Если это int, вы получите int. Если это не так, вы получите ноль. Очень просто.

Или вы можете захотеть этот метод расширения:

internal static class Extensions 
{
  public static int AsInt(this string s, int default = 0)
  {
    int result;
    if (s == null)
      return default;
    else if (int.TryParse(s, out result))
      return result;
    else
      return default;
  }
}

И теперь вы можете сказать, что вы хотите по умолчанию, не используя ??,

Этот стиль программирования называется "свободное программирование"; он может создавать код, который очень легко читать и понимать.

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

Это идеальное время, чтобы использовать метод, чтобы не повторяться:

private static int GetInputAsInt(TextBox textbox)
{
    int outputValue = 0;
    if(textbox?.Text != null && int.TryParse(textbox.Text, out outputValue))
    {  
        return outputValue;
    }
    return 0;
}

Теперь вы проверяете, не является ли само текстовое поле не нулевым, и что содержащееся в нем значение является int, если что-то не получается, оно возвращает 0;

Вызовите его в другом методе, например так:

int classANum = GetInputAsInt(txtNumberOfClassATix);

Что означает, что ваше событие нажатия кнопки будет немного проще:

private void btnCalculate_Click(object sender, EventArgs e)
{
    int classANum = GetInputAsInt(txtNumberOfClassATix);
    int classBNum = GetInputAsInt(txtNumberOfClassBTix);
    int classCNum = GetInputAsInt(txtNumberOfClassCTix);
    double classATotal = classANum * classAPrice;
    double classBTotal = classBNum * classBPrice;
    double classCTotal = classCNum * classCPrice;
    lblCalculatedClassARevenue.Text = $"{classATotal:c}";
    lblCalculatedClassBRevenue.Text = $"{classBTotal:c}";
    lblCalculatedClassCRevenue.Text = $"{classCTotal:c}";
    lblCalculatedTotalRevenue.Text = $"{(classATotal + classBTotal) + classCTotal:c}";
}

Для простоты хорошим подходом является использование условного оператора. Полный пример ниже (разбит на две строки для удобства чтения):

txtNumberOfClassATix.Text = 
    String.IsNullOrEmpty(txtNumberOfClassATix.Text) ? "0" : txtNumberOfClassATix.Text;

Это хорошее, читаемое задание для первой части:

myString = ...

Условный оператор ломается, предоставляя логическое выражение (true/ false) на левой стороне ?, Так, например:

myString = anotherString == "" ? ... // checking if another string is empty

Заключительная часть :, Слева находится присвоение, если выражение trueи справа идет присвоение, если выражение false, Чтобы закончить пример:

myString = anotherString == "" ? "anotherString is empty" : "anotherString is not empty";

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

if (anotherString == "")
{
    myString = "anotherString is empty";
}
else
{
    myString = "anotherString is not empty";    
}

Это может относиться ко всем утверждениям. Документация находится здесь.

Лучший способ сократить количество строк кода - использовать функцию для ваших общих операций. В вашем случае вы можете создать функцию, которая проверяет, является ли объект пустым или пустым. На основе возвращаемого значения этой функции вы можете продолжить. С другой стороны, вы можете справиться с этим во внешнем интерфейсе, используя различные валидаторы, такие как RequiredFieldValidator, CustomValidator и т. Д.

Другие вопросы по тегам