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. Возможная оптимизация
- Посмотрите на ответ другого. Некоторые, вероятно, помогут вам.
- E сть
System.Net.IPAdress
класс Это обеспечивает набор методов для игры с IP-адресами (особенноTryParse
метод). - Не знаю ваших деловых требований, но ваш код не будет поддерживать IP V6. Мы на пороге (по крайней мере) развертывания IP V6. Возможно, вам следует использовать только одно текстовое поле + класс IP Address, чтобы избежать будущих ограничений.
- Если вы хотите иметь несколько полей 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 в качестве параметра, чтобы установить цвет / ошибку.