Избегайте повторения условий в лестнице if-else - PullRequest
0 голосов
/ 02 февраля 2019

У меня есть четыре флажка.Ниже один мой код.Мой вопрос заключается в том, как избежать дублирования кода для комбинации проверки состояния.

Код:

if (chk1.Checked)
{
   if (chk2.Checked)
   {
      if (chk3.Checked)
      {
         if (chk4.Checked)
         {

         }
         else
         {

         }
      }
      else
      {
         if (chk4.Checked)
         {

         }
         else
         {

         }
      }
   }
}

То же самое можно сделать с другой частью.

Редактировать: я просто хочудобавить элемент в список строки, если условие истинно.

Ответы [ 2 ]

0 голосов
/ 02 февраля 2019

Одним из вариантов является создание словаря действий заранее.

Например,

var states = new[]
                { 
                    new { Checkboxes= new []{chk1,chk2,chk3,chk4},Action = new Action(()=>{ /* Do something */ })},
                    new { Checkboxes= new []{chk1,chk2,chk3},Action = new Action(()=>{ /* Do something */ })},
                    new { Checkboxes= new []{chk1,chk2,chk4},Action = new Action(()=>{ /* Do something */})},
                // and so on
                };


states.First(x=>x.Checkboxes.All(c=>c.Checked)).Action();
0 голосов
/ 02 февраля 2019

Если вам просто интересно, как получить доступ к каждой комбинации флажков, вы можете сделать то, что делаете, или вы можете объединить if s

if (chk1.Checked && chk2.Checked && chk3.Checked && chk4.Checked)
// do something
else if (chk1.Checked && chk2.Checked && chk3.Checked && !chk4.Checked) 
// do something
else if (chk1.Checked && chk2.Checked && !chk3.Checked && chk4.Checked) 
...

или немного поразмышлять с Биты , Двоичные литералы (C # 7) и switch вы могли бы сделать что-то такое

int BoolsToInt(params bool[] values) 
     => values.Aggregate(0, (current, value) => current << (value ? 1 : 0));

...

var val = BoolsToInt(chk1.Checked, chk2.Checked, chk3.Checked, chk4.Checked);
switch (val)
{
   case 0b0000: break;
   case 0b0001: break;
   case 0b0010: break;
   case 0b0011: break;
   case 0b0100: break;
   case 0b0101: break;
   case 0b0110: break;
   case 0b0111: break;
   case 0b1000: break;
   case 0b1001: break;
   case 0b1010: break;
   case 0b1011: break;
   case 0b1100: break;
   case 0b1101: break;
   case 0b1110: break;
   case 0b1111: break;
}

Примечание Я не совсем уверен, что последний вариант более понятен, и это было больше, потому что я просто хотел использовать двоичные литералы.ifs, вероятно, лучший вариант

или вдохновлен другим ответом

private static Dictionary<int, Action> _dict;

...

_dict = new Dictionary<int, Action>()
               {
                  { 0b0000, () => DoStuff0() },
                  { 0b0001, () => DoStuff1() },
                  { 0b0010, () => DoStuff2() },
                  { 0b0011, () => DoStuff3() },
                  { 0b0100, () => DoStuff4() },
                  { 0b0101, () => DoStuff5() },
                  { 0b0110, () => DoStuff6() },
                  { 0b0111, () => DoStuff7() },
                  { 0b1000, () => DoStuff8() },
                  { 0b1001, () => DoStuff9() },
                  { 0b1010, () => DoStuff10() },
                  { 0b1011, () => DoStuff11() },
                  { 0b1100, () => DoStuff12() },
                  { 0b1101, () => DoStuff13() },
                  { 0b1110, () => DoStuff14() },
                  { 0b1111, () => DoStuff15() },
               };

Использование

var combination = BoolsToInt(chk1.Checked, chk2.Checked, chk3.Checked, chk4.Checked);
dict[combination].Invoke();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...