如何清理if else系列

时间:2017-02-28 09:46:46

标签: c# coding-style

在C#中工作,想要减少if else系列,实体有两个属性FromServiceIDToServiceID,假设我的ServiceClass实例有以下信息。如何清理以下代码?任何类型的建议都是可以接受的。

entity= new ServiceClass();
entity.FromServiceID=3
entity.ToServiceID=1

if (entity.FromServiceID == 1)
{
    entity.1KWithdrawal();
}
else if (entity.FromServiceID == 2)
{
    entity.10KWithdrawal();
}
else if (entity.FromServiceID == 3)
{
    entity.BTWithdrawal();
}           
if (entity.ToServiceID == 1)
{
    entity.1KDeposit();
}
else if (entity.ToServiceID == 2)
{
    entity.10KDeposit();
}
else if (entity.ToServiceID == 3)
{
    entity.BTDeposit();
}


public class ServiceClass
{ 

    public int FromServiceID { get; set; }
    public int ToServiceID { get; set; }

    public void 1KWithdrawal()
    { Console.WriteLine("One_KWithdrawal"); }

    public void 10KWithdrawal()
    { Console.WriteLine("Ten_KWithdrawal"); }

    public void BTWithdrawal()
    { Console.WriteLine("BTWithdrawal"); }

    public void 1KDeposit()
    { Console.WriteLine("One_KDeposit"); }

    public void 10KDeposit()
    { Console.WriteLine("Ten_KDeposit"); }

    public void BTDeposit()
    { Console.WriteLine("Ten_KDeposit"); }
}

4 个答案:

答案 0 :(得分:3)

使用Dictionary。像这样:

Dictionary<int, ServiceClass> dictionary = new Dictionary<int, ServiceClass>()
{
    {1,  new ServiceClass()},
    {2,  new ServiceClass()},
    {3,  new BTWithdrawal()},//assume BTWithdrawal inherits from ServiceClass
};

使用它的一个例子:

ServiceClass value=new ServiceClass();
value.FromServiceId=1;
value.ToServiceId = 2;
dictionary.TryGetValue(value.FromServiceId, out value);
//or dictionary.TryGetValue(value.ToServiceId, out value);
if (value != null) MessageBox.Show(value.Id.ToString());

答案 1 :(得分:1)

也许这是一种矫枉过正,但你可以为你的每个案例创建一个类,它继承自一个公共接口(让我们称之为ICommon),为每种情况公开一种通用方法(在你的情况下是一个创建方法)然后在ServiceClass

的构造函数中注入该接口

然后当你想使用ServiceClass时,你必须提供ICommon的实际实现(你从每个案例中提取的一个类),最后你只需要调用{{1 }}

我认为这是策略模式,总的来说,你应该在一个通用接口下的不同类中提取算法。

最后,这种重构会降低代码的分圆复杂性(这主要意味着你减少代码的分支),这总是一件好事。

答案 2 :(得分:0)

您可以使用以下开关案例:

var entity = new ServiceClass();

entity.FromServiceID = 3;
entity.ToServiceID = 1;

switch(entity.FromServiceID)
{
    case 1:
        new 1KWithdrawal();
        break;
    case 2:
        new 10KWithdrawal();
        break;
    case 3:
        new BTWithdrawal();
        break;
}

switch(entity.ToServiceID)
{
    case 1:
        new 1KDeposit();
        break;
    case 2:
        new 10KDeposit();
        break;
    case 3:
        new BTDeposit();
        break;
}

答案 3 :(得分:0)

您可以做的是将所有变体放入枚举中,并调用枚举值,就像您想要调用的方法一样。 (我建议不要在名称中使用数字,因为编译器不允许使用数字)

为了简单和可测试性,我将枚举和方法放在同一个类中:

public class ServiceClass
{
    public enum ServiceID
    {
        OneKWithdrawal,
        Ten_KWithdrawal,
        BTWithdrawal,
        OneKDeposit,
        Ten_KDeposit,
        BTDeposit
    }
    public ServiceID From_Ser_ID { get; set; }
    public ServiceID To_Ser_ID { get; set; }

    public void One_KWithdrawal()
    { Console.WriteLine("One_KWithdrawal"); }

    public void Ten_KWithdrawal()
    { Console.WriteLine("Ten_KWithdrawal"); }

    public void BTWithdrawal()
    { Console.WriteLine("BTWithdrawal"); }

    public void One_KDeposit()
    { Console.WriteLine("One_KDeposit"); }

    public void Ten_KDeposit()
    { Console.WriteLine("Ten_KDeposit"); }
}

这将是执行if-condition方法的方法。它使用反射来访问枚举中编码的方法。您可能需要调整object调用中的Invoke(sc, null);参数,具体取决于您的方法所在的位置。如果他们与您拨打execute的班级属于同一班级,则可以使用this

public static void execute(ServiceClass sc)
{
    sc.GetType().GetMethod(sc.From_Ser_ID.ToString()).Invoke(sc, null);
    sc.GetType().GetMethod(sc.To_Ser_ID.ToString()).Invoke(sc, null);
}

在这里你可以测试整个代码:

public static void Main(string[] args)
{

    ServiceClass entity = new ServiceClass();
    entity.From_Ser_ID = ServiceClass.ServiceID.BTWithdrawal;
    entity.To_Ser_ID = ServiceClass.ServiceID.Ten_KDeposit;

    execute(entity);
}

所以你最终得到一个枚举和两行代码。