【问题标题】:Best way to handle redundant code that has repeated logic?处理具有重复逻辑的冗余代码的最佳方法?
【发布时间】:2017-01-13 04:43:33
【问题描述】:

在我的表单中,我有四个RadioButtons,根据用户选择,执行此代码:

private void button1_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
            if (radioButtonName.Checked)
            {
                var Qr = from n in mylist where n.Name == textBoxSearch.Text select new { n.Name, n.Age, n.Occu, n.Gender };
                foreach (var item in Qr)
                {
                    listBox1.Items.Add("Name: " + item.Name + "   " + "  Age: " + item.Age + "   " + "  Occupation: " + item.Occu + "   " + "  Gender: " + item.Gender);
                }
            }
            if (radioButtonAge.Checked)
            {
                var Qr = from n in mylist where n.Age == textBoxSearch.Text select new { n.Name, n.Age, n.Occu, n.Gender };
                foreach (var item in Qr)
                {
                    listBox1.Items.Add("Name: " + item.Name + "   " + "  Age: " + item.Age + "   " + "  Occupation: " + item.Occu + "   " + "  Gender: " + item.Gender);
                }

            }
            if (radioButtonGender.Checked)
            {
                var Qr = from n in mylist where n.Gender == textBoxSearch.Text select new { n.Name, n.Age, n.Occu, n.Gender };
                foreach (var item in Qr)
                {
                    listBox1.Items.Add("Name: " + item.Name + "   " + "  Age: " + item.Age + "   " + "  Occupation: " + item.Occu + "   " + "  Gender: " + item.Gender);
                }
            }
            if (radioButtonOccupation.Checked)
            {
                var Qr = from n in mylist where n.Occu == textBoxSearch.Text select new { n.Name, n.Age, n.Occu, n.Gender };
                foreach (var item in Qr)
                {
                    listBox1.Items.Add("Name: " + item.Name + "   " + "  Age: " + item.Age + "   " + "  Occupation: " + item.Occu + "   " + "  Gender: " + item.Gender);
                }

            }

        }

代码看起来非常冗余和重复,但我也找不到一种方法来处理一行中的所有 4 个单选按钮,该单行按钮只有一个与用户选择相关联的变量。 myList 是我创建的一个类的 List,它有 4 个 string 属性(NameAgeGenderOccu

【问题讨论】:

    标签: c# linq loops if-statement


    【解决方案1】:

    唯一的区别在于 filter (where) 所有其他的都可以组合:

     private void button1_Click(object sender, EventArgs e) {
       var lines = mylist
         .Where(item => radioButtonName.Checked && item.Name == textBoxSearch.Text ||
                        radioButtonAge.Checked && item.Age == textBoxSearch.Text ||
                        radioButtonGender.Checked && item.Gender == textBoxSearch.Text ||
                        radioButtonOccupation.Checked && item.Occu == textBoxSearch.Text)
         .Select(item => string.Format("Name: {0} Age: {1} Occupation: {2} Gender: {3}",
                                        item.Name, item.Age, item.Occu, item.Gender));  
    
       listBox1.Items.Clear();
    
       foreach (string line in lines)
         listBox1.Items.Add(line);   
     }  
    

    【讨论】:

    • 快速提问单选按钮检查和文本比较应该用括号括起来还是无关紧要?例如(radioButtonName.Checked && item.Name == textBoxSearch.Text) || (radioButtonAge.Checked && item.Age == textBoxSearch.Text)...
    • @Nkosi:在上下文中无关紧要;但是,如果带括号的版本更适合您可读,您可以添加(...)
    • @Nkosi 见this answer&&s 首先得到评估
    • @OrkhanAlikhanov 谢谢。在我脑海中走过之后,我想通了。
    • 你还应该重写 ToString,或者为你的类创建一个名为 ToListboxString 的方法。
    【解决方案2】:

    您可以使用字典一次性将RadioButton 映射到其Filter。假设MyClass 是您列表中的对象类型:

    private void button1_Click(object sender, EventArgs e)
    {
       var mapping = new Dictionary<RadioButton, Func<MyClass, bool>>()
       {
          { radioButtonName , x => x.Name == textBoxSearch.Text },
          { radioButtonAge, x => x.Age == textBoxSearch.Text },
          { radioButtonGender, x => x.Gender == textBoxSearch.Text},
          { radioButtonOccupation, x => x.Occu == textBoxSearch.Text}
       };
    
       foreach(var map in mapping.Where(x=> x.Key.Checked))
       {
           var Qr = mylist.Where(map.Value).Select(n=> new {n.Name, n.Age, n.Occu, n.Gender});
           foreach (var item in Qr)
           {
              listBox1.Items.Add("Name: " + item.Name + "   " + "  Age: " + item.Age + "   " 
                               + "  Occupation: " + item.Occu + "   " + "  Gender: " 
                               + item.Gender);
           }
       }
    
    }
    

    通过这种方式,您可以使用字典中的简单行轻松插入新的单选按钮。

    【讨论】:

      【解决方案3】:

      您可以首先生成一个匿名列表,其中包含单选按钮和预测位置,然后对其进行迭代(在这种情况下,MyItem 是您的列表包含的示例/占位符,因为我不知道实际的类名):

          private void button1_Click(object sender, EventArgs e)
          {
              // Generate anonymous list of objects that are different
              var radios = new[]
              {
                  new { RadioButton = radioButtonName, CallBack = new Func<MyItem, bool>(x => x.Name == textBoxSearch.Text) },
                  new { RadioButton = radioButtonAge, CallBack = new Func<MyItem, bool>(x => x.Age == textBoxSearch.Text) },
                  new { RadioButton = radioButtonGender, CallBack = new Func<MyItem, bool>(x => x.Occu == textBoxSearch.Text) },
                  new { RadioButton = radioButtonOccupation, CallBack = new Func<MyItem, bool>(x => x.Gender == textBoxSearch.Text) },
              };
      
              // Iterate through list and add items to ListBox1, if RadioButtton is checked
              listBox1.Items.Clear();
              foreach (var radio in radios)
              {
                  if (!radio.RadioButton.Checked)
                  {
                      continue;
                  }
                  var Qr = mylist.Where(radio.CallBack).Select(n => new { n.Name, n.Age, n.Occu, n.Gender });
                  foreach (var item in Qr)
                  {
                      listBox1.Items.Add($"Name: {item.Name}     Age: {item.Age}     Occupation: {item.Occu}     Gender: {item.Gender}");
                  }
              }
          }
      

      【讨论】:

        【解决方案4】:

        将所有内容都包装在这样的函数中:

        public void foo(RadioButton radioButton, Expression<Func<MyItem, bool>> expression)
            {
                if (radioButton.Checked)
                {
                    var Qr = mylist.AsQueryable().Where(expression).Select(x => String.Format("Name: {0}, Age: {1}, Occ: {2}, Gender: {3}", x.Name, x.Age, x.Occu, x.Gender)).ToList();
        
                    foreach (var item in Qr)
                    {
                        listBox1.Items.Add(item);
                    }
                }
            }
        
            private void button1_Click(object sender, EventArgs e)
            {
                listBox1.Items.Clear();
                foo(radioButtonName, c => c.Gender == textBoxSearch.Text);
                foo(radioButtonAge, c => c.Age == textBoxSearch.Text);
                foo(radioButtonGender, c =>  c.Gender == textBoxSearch.Text);
                foo(radioButtonOccupation, c => c.Occu == textBoxSearch.Text);
            }
        
        
        
        public class MyItem
            {
                public String Occu { get; set; }
        
                public String Age { get; set; }
                public String Name { get; set; }
                public String Gender { get; set; }
        
            }
        

        【讨论】:

          猜你喜欢
          • 2021-05-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-12
          • 1970-01-01
          相关资源
          最近更新 更多