Производительность и читаемость 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 должен обеспечить некоторую возможность привязки данных.

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