Производительность и читаемость C# с кнопками включения / выключения
Я часто оказывался перед таким кодом:
if(Something > 0)
{
btnOne.Enabled = true;
btnTwo.Enabled = true;
btnThree.Enabled = false:
}
else
{
btnOne.Enabled = false;
btnTwo.Enabled = false;
btnThree.Enabled = true:
}
И я всегда задавался вопросом, лучше ли было бы позволить этому так или выразиться так:
bool ButtonEnabled = (Something > 0);
btnOne.Enabled = ButtonEnabled;
btnTwo.Enabled = ButtonEnabled;
btnThree.Enabled = !ButtonEnabled;
Понимание того, что вопрос является немного спорным, давайте оставим в стороне фактор "читаемости" и сконцентрируемся на факторе производительности... Что было бы лучше? Еще одно назначение или условие?
Заранее спасибо за ваши советы (или даже лучший способ написать это)!
Изменить: Исправлена ошибка в моем втором фрагменте. Изменить: два первоначальных примера не были эквивалентны...
4 ответа
Это зависит от вызываемых свойств. Как вы знаете, недвижимость может приносить любую прибыль. В Windows Forms или WPF я бы об этом не беспокоился. Я бы поспорил за последний стиль для правильности и читабельности. Если вы устанавливаете все необходимые переменные каждый раз, меньше вероятность пропустить что-то и оставить одну кнопку в недопустимом состоянии.
Я бы сделал что-то вроде
bool ButtonEnabled = (Something > 0);
btnOne.Enabled = ButtonEnabled;
btnTwo.Enabled = ButtonEnabled;
btnThree.Enabled = !ButtonEnabled;
btnFour.Enabled = !ButtonEnabled;
Вы не можете сравнить эти две части кода ни по удобочитаемости, ни по производительности, так как они дают разные результаты.
Версия первого кода, эквивалентная второму, будет иметь вид:
if(Something > 0)
{
btnOne.Enabled = true;
btnTwo.Enabled = true;
btnThree.Enabled = false;
btnFour.Enabled = false;
}
else
{
btnOne.Enabled = false;
btnTwo.Enabled = false;
btnThree.Enabled = true;
btnFour.Enabled = true;
}
Версия второго кода, эквивалентная первому, будет иметь вид:
bool ButtonEnabled = (Something > 0);
btnOne.Enabled = ButtonEnabled ? true : btnOne.Enabled;
btnTwo.Enabled = ButtonEnabled ? true : btnTwo.Enabled;
btnThree.Enabled = !ButtonEnabled ? false : btnThree.Enabled;
btnFour.Enabled = !ButtonEnabled ? false : btnFour.Enabled;
Итак, первый фрагмент кода явно более эффективен и удобочитаем, чем его эквивалентная альтернатива, а второй фрагмент кода короче и несколько проще в обслуживании, чем его эквивалентная альтернатива.
Какую бы разницу в производительности вы ни увидели между этими двумя, скорее всего, в этом случае будет незначительным, поэтому я бы выбрал наиболее читаемый.
Да, в отличие от вашего приложения отображается сто тысяч кнопок одновременно, сосредоточиться HEAVILY
на удобочитаемость, а не на микрооптимизацию! Время, которое потребуется слою пользовательского интерфейса для обновления визуального элемента вашего элемента управления, в любом случае будет в 10.000 раз длиннее, чем ваши "Включенные" назначения!
Решение 2 - это почти то, что вы захотите сделать при использовании привязки данных (вы были очень близки:p). На самом деле, вы бы написали что-то вроде:
public class MyClass {
public bool IsSomethingTrue { get; set; } // with notification on property changed
public bool IsSomethingFalse { get { return !IsSomethingTrue; } }
private AMethod() {
...
IsSomethingTrue = Something > 0;
...
}
И ваш пользовательский интерфейс будет выглядеть примерно так (приправлено WPF):
<Button IsEnabled={Binding IsSomethingTrue} /> <!-- btn 1 -->
<Button IsEnabled={Binding IsSomethingTrue} /> <!-- btn 2 -->
<Button IsEnabled={Binding IsSomethingFalse} /> <!-- btn 3 -->
<Button IsEnabled={Binding IsSomethingFalse} /> <!-- btn 4 -->
<!-- Want a 5th button ? just add it without changing your code-behind ! -->
Этот шаблон позволяет добавлять столько кнопок, сколько вы хотите, не меняя ваши методы каждый раз. Это особенно полезно, когда методы имеют тенденцию быть довольно сложным, и это улучшает удобочитаемость.
Он работает для WPF, Qt, Java, и я думаю, что Winforms должен обеспечить некоторую возможность привязки данных.