处理重复逻辑的冗余代码的最佳方法是什么?

6
在我的表单中,我有四个单选按钮,基于用户的选择,执行以下代码:
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)。

4个回答

10

把所有的内容都包装在一个类似于这个的函数中:

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; }

    }

8
唯一的区别在于筛选器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);   
 }  

1
快速问题:单选按钮的检查和文本比较应该用括号括起来吗?还是无所谓?例如:(radioButtonName.Checked && item.Name == textBoxSearch.Text) || (radioButtonAge.Checked && item.Age == textBoxSearch.Text)... - Nkosi
1
@Nkosi:在上下文中并不重要;但是,如果带括号的版本对您来说更易读,则可以添加 (...) - Dmitry Bychenko
@Nkosi 请查看这个答案&&会先被计算。 - Orkhan Alikhanov
@OrkhanAlikhanov 谢谢。在我脑海中仔细思考后,我已经解决了它。 - Nkosi
你还应该重写ToString方法,或者为你的类创建一个名为ToListboxString的方法。 - Derek
@Derek:不行,因为我在 Select 中返回了 string.Select(item => string.Format(...)); 问题中的代码使用了匿名类,我们无法在那里声明/覆盖方法。 - Dmitry Bychenko

1
你可以使用字典一次性将 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);
       }
   }

}

这样,您可以使用字典中的一行简单代码轻松添加新的单选按钮。

0
你可以先生成一个匿名列表,其中包含你的单选按钮和预测,然后通过迭代它来实现(在这种情况下,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}");
            }
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接