C# Ограничение количества кода

private void txtOctet1_TextChanged(object sender, EventArgs e)
        {
            double numCheck1;
            if (txtOctet1.Text == "")
            {
            }
            else
            {
                numCheck1 = Convert.ToDouble(txtOctet1.Text);
                if (numCheck1 < 0 | numCheck1 > 255)
                {
                    btnSubnetting.Enabled = false;
                    lblOctet1Error.Text = "Error";
                    lblOctet1Error.BackColor = Color.Red;
                    lblOctet1Error.ForeColor = Color.White;
                }
                else
                {
                    btnSubnetting.Enabled = true;
                    lblOctet1Error.Text = "No Error";
                    lblOctet1Error.BackColor = Color.White;
                    lblOctet1Error.ForeColor = Color.Black;
                }
            }
        }

Я сделал десятичный в двоичный преобразователь в C#. Этот пользователь класс, сделанный мной. Пользователь вводит свой "IP-адрес" в четыре текстовых поля (по одному на каждый октет). Приведенный выше код работает, но я не хочу повторять приведенный выше код для других третьих текстовых полей ввода октета. Как бы я справился с этим (если это возможно)

5 ответов

Решение

Вместо того, чтобы показать вам решение, давайте немного поиграем с VS:

1. Введите две переменные, которые содержат ссылки на текстовые поля и метки, и замените все используемые ниже:

private void txtOctet1_TextChanged(object sender, EventArgs e)
{
    double numCheck1;
    TextBox txtToValidate = txtOctet1; // Variable 1
    Label lblError = lblOctet1Error; // Variable 2

/* Select from here in the next step */ 
    if (txtToValidate.Text == "") // Here, txtOctet1 replaced
    {
    }
    else
    {
        numCheck1 = Convert.ToDouble(txtToValidate.Text); // Here, txtOctet1 replaced
        if (numCheck1 < 0 | numCheck1 > 255)
        {
            btnSubnetting.Enabled = false;
            lblError.Text = "Error"; // Here, lblOctet1Error replaced
            lblError.BackColor = Color.Red; // Here, lblOctet1Error replaced
            lblError.ForeColor = Color.White; // Here, lblOctet1Error replaced
        }
        else
        {
            btnSubnetting.Enabled = true;
            lblError.Text = "No Error"; // Here, lblOctet1Error replaced
            lblError.BackColor = Color.White; // Here, lblOctet1Error replaced
            lblError.ForeColor = Color.Black; // Here, lblOctet1Error replaced
        }
    }
/* Select to here in the next step */ 
}

На данный момент прогресса нет

2. Выберите код, который хотите использовать повторно

с помощью мыши или клавиатуры выберите весь код между двумя заполнителями комментариев, которые я поместил. По сути, вы должны были обернуть самое внешнее if/else заявление.

3.a Выписка по методу

Щелкните правой кнопкой мыши по выбранному коду, выберите Refactor,Extract to a method,

Выберите имя для вашего метода, например, ValidateOctet.

Подтвердить. Вы должны были извлечь логику в пользовательском методе:

private void txtOctet1_TextChanged(object sender, EventArgs e)
{
    double numCheck1;
    TextBox txtToValidate = txtOctet1; // Variable 1
    Label lblError = lblOctet1Error; // Variable 2
    ValidateOctet(txtToValidate, lblError);
    }

    private void ValidateOctet(TextBox txtToValidate, Label lblError)
    {
    if (txtToValidate.Text == "") // Here, txtOctet1 replaced
    {
    }
    else
    {
        numCheck1 = Convert.ToDouble(txtToValidate.Text); // Here, txtOctet1 replaced
        if (numCheck1 < 0 | numCheck1 > 255)
        {
            btnSubnetting.Enabled = false;
            lblError.Text = "Error"; // Here, lblOctet1Error replaced
            lblError.BackColor = Color.Red; // Here, lblOctet1Error replaced
            lblError.ForeColor = Color.White; // Here, lblOctet1Error replaced
        }
        else
        {
            btnSubnetting.Enabled = true;
            lblError.Text = "No Error"; // Here, lblOctet1Error replaced
            lblError.BackColor = Color.White; // Here, lblOctet1Error replaced
            lblError.ForeColor = Color.Black; // Here, lblOctet1Error replaced
        }
    }    
}

Все еще нет видимого прогресса

3.b (Необязательный) удалить бесполезную переменную

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

private void txtOctet1_TextChanged(object sender, EventArgs e)
{
    double numCheck1;
    ValidateOctet(txtOctet1, lblOctet1Error);
    }

4. Повторно используйте метод для всех текстовых полей

Просто позвони ValidateOctet для всех пар текстовых полей / меток:

private void txtOctet1_TextChanged(object sender, EventArgs e)
{
    double numCheck1;
    ValidateOctet(txtOctet1, lblOctet1Error);
    ValidateOctet(txtOctet2, lblOctet2Error);
    ValidateOctet(txtOctet3, lblOctet3Error);
    ValidateOctet(txtOctet4, lblOctet4Error);
    }

Прогресс: теперь у вас есть логика, определенная в одном месте

5. Возможная оптимизация

  1. Посмотрите на ответ другого. Некоторые, вероятно, помогут вам.
  2. E сть System.Net.IPAdress класс Это обеспечивает набор методов для игры с IP-адресами (особенно TryParse метод).
  3. Не знаю ваших деловых требований, но ваш код не будет поддерживать IP V6. Мы на пороге (по крайней мере) развертывания IP V6. Возможно, вам следует использовать только одно текстовое поле + класс IP Address, чтобы избежать будущих ограничений.
  4. Если вы хотите иметь несколько полей IP-адресов, вам следует подумать о том, чтобы обернуть весь пользовательский интерфейс и логику в повторно используемый UserControl.

отказ

Пожалуйста, обратите внимание, что мой ответ не был нацелен на то, чтобы найти лучшее решение, но помог вам с использованием Visual Studio и его функций рефакторинга. Довольно часто начинать с простых вещей, создавать прототипы или немного поиграть перед реальной реализацией. Инструменты рефакторинга позволяют просто перепроектировать некоторые части вашего кода.

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

Вызывайте этот метод для каждого элемента управления по очереди.

Создайте метод, который принимает TextBox и Label, и вызывайте этот метод один раз для каждого набора Textbox / Labels.

(Пример для подражания)

Вы можете прикрепить одно и то же событие TextChanged ко всем текстовым полям. Поле, сгенерировавшее событие, будет в параметре отправителя, так что вы можете получить его так TextBox txtOctet = (TextBox)sender; в случае.

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

IPAddress address = null;
IPAddress.TryParse(txtIP.Text, out address);
    if(address == null)
    {
        // Set error...
    }

Напишите метод / функцию и вызовите ее в каждом методе TextChange; Вы должны передать TextField в качестве параметра, чтобы установить цвет / ошибку.

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