避免过多if else,否则if语句为多个(9)条件

时间:2011-07-01 12:53:11

标签: c# asp.net-mvc-2 c#-4.0 if-statement

我的if else语句有9个条件,我在想是否有其他替代解决方案可以使代码干净简洁。所有9条件对asp.net mvc视图执行不同的计算。我已经包含了代码和一个显示某些条件视图的图像,希望它有意义,我正在为这种情况寻找更好更强大的解决方案..谢谢

//Condition 1
//when no selection is made for the 2 dropdownlist (garages & helmets)
if (formvalues["helmets"] == "" && formvalues["garages"] == "")
{
    ViewBag.hideHelmet = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show
    ViewBag.hideGarages = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show
    ViewBag.SelectedHelmets = 1;//
    ViewBag.SelectedGarages = 1;//
    ViewBag.TotalHelmets = 1;
    ViewBag.TotalGarages = 1;
    ViewBag.TotalAmount = 1;
    ViewBag.TotalAmount =  trackEventCost.UnitCost;
}
//Condition 2
//When garages are selected from dropdown & helmets are not selected
else if ((formvalues["helmets"] == "") && (Convert.ToInt32(formvalues["garages"]) > 0))
{
    ViewBag.hideHelmet = 0;//for jquery, This value is passed to jquery script which then decides which field to hide/show
    ViewBag.hideGarages = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show
    ViewBag.SelectedHelmets = 1;
    ViewBag.SelectedGarages = Convert.ToInt32(formvalues["garages"]);
    ViewBag.TotalHelmets = 1;
    ViewBag.TotalGarages = Convert.ToInt32(formvalues["garages"]) * getGarages.UnitCost;
    ViewBag.TotalAmount = ViewBag.TotalGarages + trackEventCost.UnitCost;
}
//Condition 3
//When helmets are selected from dropdown & garages are not selected
else if ((formvalues["garages"] == "") && (Convert.ToInt32(formvalues["helmets"]) > 0))
{
    ViewBag.hideHelmet = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show
    ViewBag.hideGarages = 0;//for jquery, This value is passed to jquery script which then decides which field to hide/show
    ViewBag.SelectedGarages = 1;
    ViewBag.SelectedHelmets = Convert.ToInt32(formvalues["helmets"]);
    ViewBag.TotalGarages = 1;
    ViewBag.TotalHelmets = Convert.ToInt32(formvalues["helmets"]) * getGarages.UnitCost;
    ViewBag.TotalAmount = ViewBag.TotalHelmets + trackEventCost.UnitCost;
}
//Condition 4
//When garages are not selected from dropdown & helmets dropdownlist is hidden on the view due to unavailablity of helmets for that event
else if (formvalues["garages"] == "" && (formvalues["helmets"] == null))
{
    ViewBag.hideHelmet = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show
    ViewBag.hideGarages = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show
    ViewBag.TotalAmount = trackEventCost.UnitCost;
}
//Condition 5
//When helmets are not selected from dropdown & garages dropdownlist is hidden on the view due to unavailablity of garages for that event
else if ((formvalues["garages"] == null) && (formvalues["helmets"] == ""))
{
    ViewBag.hideHelmet = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show
    ViewBag.hideGarages = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show
    ViewBag.SelectedHelmets = 1;
    ViewBag.TotalAmount = trackEventCost.UnitCost;
}
//Condition 6
//When both helmets and garages dropdown list is not displayed on the view as they are not present in the database
else if (formvalues["helmets"] == null && formvalues["garages"] == null)
{
    ViewBag.SelectedHelmets = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show
    ViewBag.SelectedGarages = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show
    ViewBag.TotalHelmets = 1;
    ViewBag.TotalGarages = 1;
    ViewBag.hideHelmet = 1;
    ViewBag.hideGarages = 1;
    ViewBag.TotalAmount = trackEventCost.UnitCost;
}
//Condition 7
//When garages are selected from dropdown & helmets dropdownlist is hidden on the view due to unavailablity of helmets for that event
else if (formvalues["helmets"] == null && Convert.ToInt32(formvalues["garages"]) > 0)
{
    ViewBag.hideHelmet = 0; //for jquery , This value is passed to jquery script which then decides which field to hide/show
    ViewBag.hideGarages = 1; //for jquery , This value is passed to jquery script which then decides which field to hide/show
    ViewBag.SelectedGarages = Convert.ToInt32(formvalues["garages"]);
    ViewBag.TotalGarages = Convert.ToInt32(formvalues["garages"]) * getGarages.UnitCost;
    ViewBag.TotalAmount = ViewBag.TotalGarages + trackEventCost.UnitCost;
}
//Condition 8
//When helmets are selected from dropdown & garages dropdownlist is hidden on the view due to unavailablity of garages for that event
else if (Convert.ToInt32(formvalues["helmets"]) > 0 && formvalues["garages"] == null)
{
    ViewBag.hideHelmet = 1; //for jquery , This value is passed to jquery script which then decides which field to hide/show
    ViewBag.hideGarages = 0; //for jquery , This value is passed to jquery script which then decides which field to hide/show
    ViewBag.TotalHelmets = Convert.ToInt32(formvalues["helmets"]) * getHelmets.UnitCost;
    ViewBag.TotalAmount = ViewBag.TotalHelmets + trackEventCost.UnitCost;
}
//Condition 9
//When garages and helmet both dropdown are selected
 else
{
    ViewBag.hideHelmet = 0;//for jquery , This value is passed to jquery script which then decides which field to hide/show
    ViewBag.hideGarages = 0;//for jquery , This value is passed to jquery script which then decides which field to hide/show
    ViewBag.SelectedHelmets = Convert.ToInt32(formvalues["helmets"]);
    ViewBag.SelectedGarages = Convert.ToInt32(formvalues["garages"]);
    ViewBag.TotalHelmets = Convert.ToInt32(formvalues["helmets"]) * getHelmets.UnitCost;
    ViewBag.TotalGarages = Convert.ToInt32(formvalues["garages"]) * getGarages.UnitCost;
    ViewBag.TotalAmount = ViewBag.TotalHelmets + ViewBag.TotalGarages + trackEventCost.UnitCost;
}

Some Conditions

9 个答案:

答案 0 :(得分:5)

当然,你能做的一件事就是改善你的条件写作方式。我认为通过将条件提取到方法来描述检查实际执行的操作而不是在任何地方添加注释,可能会更好。

答案 1 :(得分:3)

首先,将表单值的提取移到方法的开头,例如:

int? helmets = formvalues["helmets"] == null ?
  null : Convert.ToInt32(formvalues["helmets"];
int? garages = formvalues["garages"] == null ?
  null : Convert.ToInt32(formvalues["garages"];

然后你可以很容易地设置属性而不用任何ifs / else ifs,例如:

ViewBag.hideHelmet = helmets;
// or
someOtherProperty = helmets == null ? ... : ...

更新(关于您的评论/问题):

  • 语句?:中的x = condition ? value1 : value2运算符称为conditional operator。如果value1为真,则返回condition,否则返回value2
  • int?nullable integer,可以是整数值,也可以为null。

答案 2 :(得分:2)

为什么不专注于分配目标而不是条件?

这种情况似乎很简单,也很重复。一个样本:

ViewBag.hideHelmet = formvalues["helmets"] == ""? 1 : 0;

这不需要任何分支逻辑。

答案 3 :(得分:1)

你可以移动

ViewBag.hideHelmet = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show             
ViewBag.hideGarages = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show             
ViewBag.SelectedHelmets = 1;//             
ViewBag.SelectedGarages = 1;//             
ViewBag.TotalHelmets = 1;             
ViewBag.TotalGarages = 1;             
ViewBag.TotalAmount = 1;             
ViewBag.TotalAmount =  trackEventCost.UnitCost; 

对于某个参数为optional的方法,因为您没有在所有情况下设置所有值。其次,您可以使用ternary operator。你可以使用三元运算符,如。

  int r = 1;
  long l = r == 1 ? 1 : (r==2 ? 2 : (r==3?3:(r==4 ? 4 : 5)));

答案 4 :(得分:1)

您可以将ViewBag抽象为设置所有数据的函数。这会稍微清理一下。例如

if(...) {
   SetUpViewBag(...); }
else {
   SetUpViewBag(...); }

...

private SetUpViewBag(...)
{
   ViewBag.SelectedHelmets = prop1;
   ViewBag.SelectedGarages = prop2;
   ViewBag.TotalHelmets = prop3;
   ViewBag.TotalGarages = prop4;
   ViewBag.hideHelmet = prop5;
   ViewBag.hideGarages = prop6;
   ViewBag.TotalAmount = prop7;
}

答案 5 :(得分:1)

我会根据条件使用Factory Pattern生成您的ViewBag对象。让工厂生成所需的ViewBag并将您的对象分配给它。

以下是控制台示例中的示例(仅用于快速演示):

  class MainApp
  {
     /// <summary>
     /// Entry point into console application.
     /// </summary>
     static void Main()
     {
        ViewBagCreator creator = new ConcreteCreatorForViewBagObject();

        string garages_form_value = ""; // formvalues["garages"];
        string helmets_form_value = ""; // formvalues["helments"];

        // create viewpage
        ViewBagObject view_bag = creator.FactoryMethod(helmets_form_value,
           garages_form_value, 10, 100, 23);
        Console.WriteLine("Created {0}",
          view_bag.GetType().Name);

        // Assign your viewbag object here
        // ViewBag = view_bag;

        // Wait for user
        Console.ReadKey();
     }
  }

  /// <summary>
  /// The 'ViewBagObject' abstract class
  /// </summary>
  abstract class ViewBagObject
  {
     public int hideHelmet;
     public int hideGarages;
     public int SelectedHelmets;
     public int SelectedGarages;
     public int TotalHelmets;
     public int TotalGarages;
     public int TotalAmount;
  }

  /// <summary>
  /// A 'ViewBagNoSelection' class
  /// </summary>
  class ViewBagNoSelection : ViewBagObject
  {
     public ViewBagNoSelection(int trackEventUnitCost)
     {
        hideHelmet = 1;
        hideGarages = 1;
        SelectedHelmets = 1;
        SelectedGarages = 1;
        TotalHelmets = 1;
        TotalGarages = 1;
        TotalAmount = trackEventUnitCost;
     }
  }

  /// <summary>
  /// A 'ViewBagGaragesNoHelments' class
  /// </summary>
  class ViewBagGaragesNoHelments : ViewBagObject
  {
     public ViewBagGaragesNoHelments(int garagesValue, int garagesUnitCost, int trackEventUnitCost)
     {
        hideHelmet = 0;
        hideGarages = 1;
        SelectedHelmets = 1;
        SelectedGarages = garagesValue;
        TotalHelmets = 1;
        TotalGarages = garagesValue * garagesUnitCost;
        TotalAmount = TotalGarages * trackEventUnitCost;
     }
  }

  /// <summary>
  /// A 'ViewBagHelmentsNoGarages' class
  /// </summary>
  class ViewBagHelmentsNoGarages : ViewBagObject
  {
     public ViewBagHelmentsNoGarages(int helmetsValue, int helmentsUnitCost, int trackEventUnitCost)
     {
        hideHelmet = 0;
        hideGarages = 1;
        SelectedHelmets = helmetsValue;
        SelectedGarages = 1;
        TotalHelmets = helmetsValue * helmentsUnitCost;
        TotalGarages = 1;
        TotalAmount = TotalHelmets * trackEventUnitCost;
     }
  }

  /// <summary>
  /// The 'ViewBagCreator' abstract class
  /// </summary>
  abstract class ViewBagCreator
  {
     public abstract ViewBagObject FactoryMethod(
        string helmetsFormValue, string garagesFormValue,
        int helmetsUnitCost, int garagesUnitCost, int trackEventUnitCost);
  }

  /// <summary>
  /// A 'ConcreteCreator' class
  /// </summary>
  class ConcreteCreatorForViewBagObject : ViewBagCreator
  {
     public override ViewBagObject FactoryMethod(
        string helmetsFormValue, string garagesFormValue,
        int helmetsUnitCost, int garagesUnitCost, int trackEventUnitCost)
     {
        bool helmets_value_is_null = (helmetsFormValue == null);
        bool helmets_value_is_empty = (helmetsFormValue == "");
        bool garages_value_is_null = (garagesFormValue == null);
        bool garages_value_is_empty = (garagesFormValue == "");

        int helmets = 0;
        int garages = 0;
        int.TryParse(garagesFormValue, out garages);
        int.TryParse(helmetsFormValue, out helmets);

        bool garages_greater_than_zero = garages > 0;
        bool helmets_greater_than_zero = helmets > 0;

        if (helmets_value_is_empty && garages_value_is_empty)
        {
           return new ViewBagNoSelection(trackEventUnitCost);
        }
        else if (helmets_value_is_empty && garages_greater_than_zero)
        {
           return new ViewBagGaragesNoHelments(garages, garagesUnitCost, trackEventUnitCost);
        }
        else if (garages_value_is_empty && helmets_greater_than_zero)
        {
           return new ViewBagHelmentsNoGarages(helmets, helmetsUnitCost, trackEventUnitCost);
        }
        //...
        return null;
     }
  }

答案 6 :(得分:1)

看一下Strategy模式,对于你的情况,你必须使用每策略的方法而不是每个策略的类。

void ApplyStrategy(int? helmets, int? garages)
{
 // depends on values of helmets and garages execute appropriate strategy
}

void ApplyNoHelmetsNoGaragesStrategy()
void ApplyNoGaragesStrategy()
void ApplyNoHelmetsStrategy()
// ... 

答案 7 :(得分:1)

如何构建条件类

public class Condition
{
    public Func<bool> Match { get; set; }
    public Action Execute { get; set; }
}

并建立一个列表

        var conditions = new List<Condition>
        {
            new Condition
                {
                    Match = () => formvalues["helmets"] == "" && formvalues["garages"] == "",
                    Action = () =>
                                 {
                                      ViewBag.hideHelmet = 1;    
                                      ViewBag.hideGarages = 1;
                                      ViewBag.SelectedHelmets = 1;
                                      ...
                                 }
                },
            new Condition
                { 
                  ...
                }
         };

然后是linq:

   conditions.Where(c => c.Match()).ToList().ForEach( c => c.Execute());

答案 8 :(得分:1)

一些很棒的建议。我喜欢如下处理这些情况。我已经重构了你的代码以完全删除条件。相反,我已将每个条件的代码封装到方法中,并使用类型为int的密钥和类型为Action的值创建哈希表。我为每个头盔/车库组合派生了一个独特的值,然后将其作为相应方法的关键。

我已经为你的帖子中没有的代码包括虚拟实现,这样我就可以编译并运行我的重构示例。希望有所帮助。

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;

namespace StackOverflow
{
    public enum HelmetState { Null = 1, Empty = 2, HasValue = 3 }
    public enum GarageState { Null = 4, Empty = 5, HasValue = 6 }

    public class ReducingConditionals
    {
        private TrackEventCost trackEventCost = new TrackEventCost();
        private GetHelmets getHelmets = new GetHelmets();
        private GetGarages getGarages = new GetGarages();
        private IDictionary<int, Action> ExecuteCondition;

        //the formvalues collection
        private Hashtable _formvalues;
        public Hashtable formvalues{ get { return _formvalues ?? (_formvalues = new Hashtable()); } }

        //set up dictionary of Actions
        public ReducingConditionals()
        {
            ExecuteCondition = new Dictionary<int, Action>();
            ExecuteCondition[Key(HelmetState.Null, GarageState.Null)] = HelmetsNullGaragesNull;
            ExecuteCondition[Key(HelmetState.Null, GarageState.Empty)] = HelmetsNullGaragesEmpty;
            ExecuteCondition[Key(HelmetState.Null, GarageState.HasValue)] = HelmetsNullGaragesHasValue;
            ExecuteCondition[Key(HelmetState.Empty, GarageState.Null)] = HelmetsEmptyGaragesNull;
            ExecuteCondition[Key(HelmetState.Empty, GarageState.Empty)] = HelmetsEmptyGaragesEmpty;
            ExecuteCondition[Key(HelmetState.Empty, GarageState.Empty)] = HelmetsEmptyGaragesHasValue;
            ExecuteCondition[Key(HelmetState.HasValue, GarageState.Empty)] = HelmetsHasValueGaragesNull;
            ExecuteCondition[Key(HelmetState.HasValue, GarageState.Null)] = HelmetsHasValueGaragesEmpty;
            ExecuteCondition[Key(HelmetState.HasValue, GarageState.HasValue)] = AnyOtherCondition;
        }

        //gets a unique value for each HelmetState/GarageState combination to be used as a key to the dictionary
        private int Key(HelmetState helmetState, GarageState garageState)
        {
            return (int)helmetState + (int)garageState;
        }

        //Execute the appropriate method - n.b. no if statements in sight!
        public void DealWithConditions()
        {
            HelmetState helmetState = GetHelmetState(formvalues["helmets"]);
            GarageState garageState = GetGarageState(formvalues["garages"]);
            ExecuteCondition[Key(helmetState, garageState)]();
        }

        //assign helmet state enum
        private HelmetState GetHelmetState(object helmetValue)
        {
            if (helmetValue == null) return HelmetState.Null;
            if (helmetValue.ToString() == "") return HelmetState.Empty;
            if (Convert.ToInt32(helmetValue) > 0) return HelmetState.HasValue;
            throw new InvalidDataException("Unexpected parameter value");
        }

        //assign garage state enum
        private GarageState GetGarageState(object garageValue)
        {
            if (garageValue == null) return GarageState.Null;
            if (garageValue.ToString() == "") return GarageState.Empty;
            if (Convert.ToInt32(garageValue) > 0) return GarageState.HasValue;
            throw new InvalidDataException("Unexpected parameter value");
        }

        #region encapsulate conditions in methods
        private void AnyOtherCondition()
        {
            ViewBag.hideHelmet = 0;//for jquery , This value is passed to jquery script which then decides which field to hide/show
            ViewBag.hideGarages = 0;//for jquery , This value is passed to jquery script which then decides which field to hide/show
            ViewBag.SelectedHelmets = Convert.ToInt32(formvalues["helmets"]);
            ViewBag.SelectedGarages = Convert.ToInt32(formvalues["garages"]);
            ViewBag.TotalHelmets = Convert.ToInt32(formvalues["helmets"]) * getHelmets.UnitCost;
            ViewBag.TotalGarages = Convert.ToInt32(formvalues["garages"]) * getGarages.UnitCost;
            ViewBag.TotalAmount = ViewBag.TotalHelmets + ViewBag.TotalGarages + trackEventCost.UnitCost;
        }

        private void HelmetsHasValueGaragesNull()
        {
            ViewBag.hideHelmet = 1; //for jquery , This value is passed to jquery script which then decides which field to hide/show
            ViewBag.hideGarages = 0; //for jquery , This value is passed to jquery script which then decides which field to hide/show
            ViewBag.TotalHelmets = Convert.ToInt32(formvalues["helmets"]) * getHelmets.UnitCost;
            ViewBag.TotalAmount = ViewBag.TotalHelmets + trackEventCost.UnitCost;
        }

        private void HelmetsNullGaragesHasValue()
        {
            ViewBag.hideHelmet = 0; //for jquery , This value is passed to jquery script which then decides which field to hide/show
            ViewBag.hideGarages = 1; //for jquery , This value is passed to jquery script which then decides which field to hide/show
            ViewBag.SelectedGarages = Convert.ToInt32(formvalues["garages"]);
            ViewBag.TotalGarages = Convert.ToInt32(formvalues["garages"]) * getGarages.UnitCost;
            ViewBag.TotalAmount = ViewBag.TotalGarages + trackEventCost.UnitCost;
        }

        private void HelmetsNullGaragesNull()
        {
            ViewBag.SelectedHelmets = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show
            ViewBag.SelectedGarages = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show
            ViewBag.TotalHelmets = 1;
            ViewBag.TotalGarages = 1;
            ViewBag.hideHelmet = 1;
            ViewBag.hideGarages = 1;
            ViewBag.TotalAmount = trackEventCost.UnitCost;
        }

        private void HelmetsEmptyGaragesNull()
        {
            ViewBag.hideHelmet = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show
            ViewBag.hideGarages = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show
            ViewBag.SelectedHelmets = 1;
            ViewBag.TotalAmount = trackEventCost.UnitCost;
        }

        private void HelmetsNullGaragesEmpty()
        {
            ViewBag.hideHelmet = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show
            ViewBag.hideGarages = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show
            ViewBag.TotalAmount = trackEventCost.UnitCost;
        }

        private void HelmetsHasValueGaragesEmpty()
        {
            ViewBag.hideHelmet = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show
            ViewBag.hideGarages = 0;//for jquery, This value is passed to jquery script which then decides which field to hide/show
            ViewBag.SelectedGarages = 1;
            ViewBag.SelectedHelmets = Convert.ToInt32(formvalues["helmets"]);
            ViewBag.TotalGarages = 1;
            ViewBag.TotalHelmets = Convert.ToInt32(formvalues["helmets"]) * getGarages.UnitCost;
            ViewBag.TotalAmount = ViewBag.TotalHelmets + trackEventCost.UnitCost;
        }

        private void HelmetsEmptyGaragesHasValue()
        {
            ViewBag.hideHelmet = 0;//for jquery, This value is passed to jquery script which then decides which field to hide/show
            ViewBag.hideGarages = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show
            ViewBag.SelectedHelmets = 1;
            ViewBag.SelectedGarages = Convert.ToInt32(formvalues["garages"]);
            ViewBag.TotalHelmets = 1;
            ViewBag.TotalGarages = Convert.ToInt32(formvalues["garages"]) * getGarages.UnitCost;
            ViewBag.TotalAmount = ViewBag.TotalGarages + trackEventCost.UnitCost;
        }

        private void HelmetsEmptyGaragesEmpty()
        {
            ViewBag.hideHelmet = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show
            ViewBag.hideGarages = 1;//for jquery, This value is passed to jquery script which then decides which field to hide/show
            ViewBag.SelectedHelmets = 1;//
            ViewBag.SelectedGarages = 1;//
            ViewBag.TotalHelmets = 1;
            ViewBag.TotalGarages = 1;
            ViewBag.TotalAmount = 1;
            ViewBag.TotalAmount = trackEventCost.UnitCost;
        }
        #endregion
    }

    #region dummy class class implementations
    public class ViewBag
    {
        public static int TotalAmount;
        public static int hideHelmet { get; set; }
        public static int hideGarages { get; set; }
        public static int SelectedHelmets { get; set; }
        public static int SelectedGarages { get; set; }
        public static int TotalGarages { get; set; }
        public static int TotalHelmets { get; set; }
    }
    internal class GetGarages { public int UnitCost; }
    internal class GetHelmets { public int UnitCost; }
    internal class TrackEventCost{ public int UnitCost;}
    #endregion
}