如何简化选择(如果)

时间:2011-04-07 09:58:26

标签: c# refactoring

我有这样的代码,以使其更好(modbus_master.SetValue(“x1”,Convert.ToInt32(resipeDosings [i] .Massa)* 10,1); - 将数据发送到控制器)

 public class RecipeDosings
 {
    public string Product { get; set; }
    public string Persent { get; set; }
    public string Massa { get; set; }
    public string Bunker { get; set; }

    public RecipeDosings(string product, string persent, string massa, string bunker)
    {
        this.Product = product;
        this.Persent = persent;
        this.Massa = massa;
        this.Bunker = bunker;
    }
  }

 public List<RecipeDosings> resipeDosings = new List<RecipeDosings>();

        for (int i = 0; i < resipeDosings.Count; i++)
        {
            if (resipeDosings[i].Bunker == "Bunker 1")
            {
                modbus_master.SetValue("x1", Convert.ToInt32(resipeDosings[i].Massa) * 10, 1);      
            }
            if (resipeDosings[i].Bunker == "Bunker 2")
            {
                modbus_master.SetValue("x1", Convert.ToInt32(resipeDosings[i].Massa) * 10, 1);
            }
            if (resipeDosings[i].Bunker == "Bunker 3")
            {
                modbus_master.SetValue("x1", Convert.ToInt32(resipeDosings[i].Massa) * 10, 1);
            }
            if (resipeDosings[i].Bunker == "Bunker 4")
            {
                modbus_master.SetValue("x1", Convert.ToInt32(resipeDosings[i].Massa) * 10, 1);
            }
            if (resipeDosings[i].Bunker == "Bunker 5")
            {
                modbus_master.SetValue("x1", Convert.ToInt32(resipeDosings[i].Massa) * 10, 1);
            }
            if (resipeDosings[i].Bunker == "Bunker 6")
            {
                modbus_master.SetValue("x1", Convert.ToInt32(resipeDosings[i].Massa) * 10, 1);
            }
            if (resipeDosings[i].Bunker == "Bunker 7")
            {
                modbus_master.SetValue("x1", Convert.ToInt32(resipeDosings[i].Massa) * 10, 1);
            }
            if (resipeDosings[i].Bunker == "Bunker 8")
            {
                modbus_master.SetValue("x1", Convert.ToInt32(resipeDosings[i].Massa) * 10, 1);
            }
            if (resipeDosings[i].Bunker == "Bunker 9")
            {
                modbus_master.SetValue("x1", Convert.ToInt32(resipeDosings[i].Massa) * 10, 1);
            }
        }

7 个答案:

答案 0 :(得分:7)

Switch语句删除所有if语句 -

switch (resipeDosings[i].Bunker)
{
case "Bunker 1":
    // code here
    break;
case "Bunker 2":
    // code here
    break;

    // repeat case statements...

default:
    // this is the final 'else' code - if nothing matches
}

然而,有两件事是显而易见的:

  • 无论
  • ,您都在执行相同的代码
  • 您应该在查找表或数据库表中存储变量(每个Bunker可能不同的变量),因此每次获得新Bunker或想要更改时都不需要修改程序值

构建LUT的最简单方法是使用Dictionary<>

Dictionary<string, int> bunkerLut = new Dictionary<string, int>();

bunkerLut["Bunker 1"] = 10;
bunkerLut["Bunker 2"] = 11;
bunkerLut["Bunker 3"] = 12;

// and so on... I'm assuming there should be a value that's different for each bunker?  I'm also assuming it's an int

然后你可以查找,就像这样(假设10是值的变化):

int result = bunkerLut[resipeDosings[i].Bunker];
modbus_master.SetValue("x1", Convert.ToInt32(resipeDosings[i].Massa) * result, 1);

其他选项是将值存储在配置文件或数据库中。

答案 1 :(得分:3)

您可以执行以下操作:

for (int i = 0; i < resipeDosings.Count; i++)
{
    switch(resipeDosings[i].Bunker)
    {
        case "Bunker 1":
        case "Bunker 2":
        case "Bunker 3":
        case "Bunker 4":
        case "Bunker 5":
        case "Bunker 6":
        case "Bunker 7":
        case "Bunker 8":
        case "Bunker 9":
        case "Bunker 10":
            modbus_master.SetValue("x1", Convert.ToInt32(resipeDosings[i].Massa) * 10, 1);
            break;
        default:
            break;
    }
}

答案 2 :(得分:2)

嗯,只要你对待他们的方式没有区别:

public List<RecipeDosings> resipeDosings = new List<RecipeDosings>();

for (int i = 0; i < resipeDosings.Count; i++)
{
    if (resipeDosings[i].Bunker.StartsWith("Bunker "))
    {
        modbus_master.SetValue("x1", Convert.ToInt32(resipeDosings[i].Massa) * 10, 1);      
    }
}

答案 3 :(得分:1)

由于对不同值的操作似乎没有区别,您只需验证它是要检查的值之一,并在这种情况下执行操作:

var valuesToCheck = new[] { 
    "Bunker 1",
    "Bunker 2",
    "Bunker 3",
    "Bunker 4",
    "Bunker 5",
    "Bunker 6",
    "Bunker 7",
    "Bunker 8",
    "Bunker 9"};

for (int i = 0; i < resipeDosings.Count; i++)
{                
    if (valuesToCheck.Contains(resipeDosings[i].Bunker)
    {
        modbus_master.SetValue("x1", Convert.ToInt32(resipeDosings[i].Massa) * 10, 1);      
    }    
}

答案 4 :(得分:1)

我可能会忽视某些事情,但每个掩体情况都没有区别。

for (int i = 0; i < resipeDosings.Count; i++)
    modbus_master.SetValue("x1", Convert.ToInt32(resipeDosings[i].Massa) * 10, 1);

这样做会完全一样。

答案 5 :(得分:0)

还有一件事:
如果你以你的方式使用if,即检查一次只能有一个为真,请使用else if,这样它就不会计算已知为false的表达式:

if(cond1)
{
   // do stuff
}
else if(cond2)
{
   // do stuff
}
else if(cond3)
{
   // do stuff
}

但是,如果没有更好的选择,例如switch或其他......

,请这样做

答案 6 :(得分:0)

我有一个string / func的字典,就像这样;

class EmirateRefactored
{
    public List<RecipeDosings> resipeDosings = new List<RecipeDosings>();
    private Dictionary<string, Func<RecipeDosings, int>> m_objActionMapping;

    public EmirateRefactored()
    {
        m_objActionMapping = new Dictionary<string, Func<RecipeDosings, int>>();
        m_objActionMapping.Add("Bunker 1", bunker1);
        m_objActionMapping.Add("Bunker 2", bunker2);
        //etc
    }

    public void Process(ModBusMaster modbus_master)
    {
        foreach (RecipeDosings rd in resipeDosings)
        {
            if (m_objActionMapping.ContainsKey(rd.Bunker))
            {
                int result = m_objActionMapping[rd.Bunker].Invoke(rd);
                modbus_master.SetValue(result);
            }
            else
                throw new ApplicationException("Couldn't parse bunker!");
        }
    }

    /// <summary>
    /// I have no idea what this is as it's not included in the sample code!
    /// </summary>
    public class ModBusMaster
    {
        public void SetValue(int i_intInput) { }
    }

    /// <summary>
    /// Some code relevant to "bunker 1"
    /// </summary>
    private int bunker1(RecipeDosings i_objRecipe)
    {
        return Convert.ToInt32(i_objRecipe.Massa) * 10;
    }
    /// <summary>
    /// Some code relevant to "bunker 2"
    /// </summary>
    private int bunker2(RecipeDosings i_objRecipe)
    {
        //bunker2 code
        return Convert.ToInt32(i_objRecipe.Massa) * 10;
    }
}

我做了几个假设,如果没有更多的示例代码/示例匹配等,就不知道实际要求是什么。

编辑:在阅读其他答案的一些评论后,您可以很容易地将其修改为Regex / func的字典。并从过程方法;如果“Bunker”属性与正则表达式匹配则调用func。