【问题标题】:How to optimize an if statement inside a switch statement如何优化 switch 语句中的 if 语句
【发布时间】:2019-11-23 21:16:36
【问题描述】:

我想知道是否可以优化下面的代码,这样我就不必在每个 case 语句中都有一个“if”语句?减少/最小化代码...

仅供参考 - if 语句在传入生产接口(例如 ARMProduction.WebServiceAWI)和生产对象(例如 new ARMProduction.User())之间切换 而且它们来自不同的接口,所以我认为我不能创建一个接口并通过它。

switch(claimParams.ServiceName) {
case "ARM":
    if (_environment.Production)
       claimResult = await WebService<ARMProduction.WebServiceAWI>.GetClaim(claimParams, _environment.ARMUrl, _environment.TrustOnlineUsername, _environment.TrustOnlinePassword, new ARMProduction.User());     
    else
       claimResult = await WebService<ARMDevelopment.WebServiceAWI>.GetClaim(claimParams, _environment.ARMUrl, _environment.TrustOnlineUsername, _environment.TrustOnlinePassword, new ARMDevelopment.User());
    break;
case "BW":
    if (_environment.Production)
       claimResult = await WebService<BWProduction.WebServiceBW>.GetClaim(claimParams, _environment.BWUrl, _environment.TrustOnlineUsername, _environment.TrustOnlinePassword, new BWProduction.User());     
    else
       claimResult = await WebService<BWDevelopment.WebServiceBW>.GetClaim(claimParams, _environment.BWUrl, _environment.TrustOnlineUsername, _environment.TrustOnlinePassword, new BWDevelopment.User());
    break;
case "CS":
    if (_environment.Production)
       claimResult = await WebService<CSProduction.WebServiceCS>.GetClaim(claimParams, _environment.CSUrl, _environment.TrustOnlineUsername, _environment.TrustOnlinePassword, new CSProduction.User());     
    else
       claimResult = await WebService<CSDevelopment.WebServiceCS>.GetClaim(claimParams, _environment.CSUrl, _environment.TrustOnlineUsername, _environment.TrustOnlinePassword, new CSDevelopment.User());
    break;
}

【问题讨论】:

  • Dictionary&lt;string, Func&lt;Task&lt;ClaimResult&gt;&gt;&gt;
  • 嗨。你能提供一个更完整的例子吗?
  • 你有一个简单的决策树,在当前的样本中,它的大小和复杂性我会保持原样。但是,如果您发现自己通过添加/删除新案例或新环境来不断更改它,那么您可能可以将可更改部分移动到专用结构中,添加和删除它们不需要更改决策逻辑。

标签: c# if-statement interface switch-statement


【解决方案1】:

不,不是。

我认为“优化”它(如您所说)的最佳方法是使其尽可能可读。它已经很难阅读,并且错误有办法在这些代码区域中找到归宿。

所以,不,我不建议尝试花哨并使用条件运算符或任何会使代码的可读性降低的东西。

就个人而言,如果从 switch 语句中删除 if 语句,我会更喜欢它。这段代码应该是等价的,但我认为可读性更强:

if (_environment.Production)
{
    switch(claimParams.ServiceName)
    {
        case "ARM":
            claimResult = await WebService<ARMProduction.WebServiceAWI>.GetClaim(claimParams, _environment.ARMUrl, _environment.TrustOnlineUsername, _environment.TrustOnlinePassword, new ARMProduction.User());     
            break;
        case "BW":
            claimResult = await WebService<BWProduction.WebServiceBW>.GetClaim(claimParams, _environment.BWUrl, _environment.TrustOnlineUsername, _environment.TrustOnlinePassword, new BWProduction.User());     
            break;
        case "CS":
            claimResult = await WebService<CSProduction.WebServiceCS>.GetClaim(claimParams, _environment.CSUrl, _environment.TrustOnlineUsername, _environment.TrustOnlinePassword, new CSProduction.User());     
            break;
    }
}
else
{
    switch(claimParams.ServiceName)
    {
        case "ARM":
            claimResult = await WebService<ARMDevelopment.WebServiceAWI>.GetClaim(claimParams, _environment.ARMUrl, _environment.TrustOnlineUsername, _environment.TrustOnlinePassword, new ARMDevelopment.User());
            break;
        case "BW":
            claimResult = await WebService<BWDevelopment.WebServiceBW>.GetClaim(claimParams, _environment.BWUrl, _environment.TrustOnlineUsername, _environment.TrustOnlinePassword, new BWDevelopment.User());
            break;
        case "CS":
            claimResult = await WebService<CSDevelopment.WebServiceCS>.GetClaim(claimParams, _environment.CSUrl, _environment.TrustOnlineUsername, _environment.TrustOnlinePassword, new CSDevelopment.User());
            break;
    }
}

【讨论】:

    【解决方案2】:

    从 C# 7 开始,您可以在 switch 语句中使用 when 子句 (https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/switch#-the-case-statement-and-the-when-clause)

    这看起来像:

    switch (claimParams.ServiceName)
    {
        case "ARM" when _environment.Production:
            claimResult = await WebService<ARMProduction.WebServiceAWI>.GetClaim(claimParams, _environment.ARMUrl, _environment.TrustOnlineUsername, _environment.TrustOnlinePassword, new ARMProduction.User());
            break;
        case "ARM" when !_environment.Production:
            claimResult = await WebService<ARMDevelopment.WebServiceAWI>.GetClaim(claimParams, _environment.ARMUrl, _environment.TrustOnlineUsername, _environment.TrustOnlinePassword, new ARMDevelopment.User());
            break;
        case "BW" when _environment.Production:
            claimResult = await WebService<BWProduction.WebServiceBW>.GetClaim(claimParams, _environment.BWUrl, _environment.TrustOnlineUsername, _environment.TrustOnlinePassword, new BWProduction.User());
            break;
        case "BW" when !_environment.Production:
            claimResult = await WebService<BWDevelopment.WebServiceBW>.GetClaim(claimParams, _environment.BWUrl, _environment.TrustOnlineUsername, _environment.TrustOnlinePassword, new BWDevelopment.User());
            break;
        case "CS" when _environment.Production:
            claimResult = await WebService<CSProduction.WebServiceCS>.GetClaim(claimParams, _environment.CSUrl, _environment.TrustOnlineUsername, _environment.TrustOnlinePassword, new CSProduction.User());
            break;
        case "CS" when !_environment.Production:
            claimResult = await WebService<CSDevelopment.WebServiceCS>.GetClaim(claimParams, _environment.CSUrl, _environment.TrustOnlineUsername, _environment.TrustOnlinePassword, new CSDevelopment.User());
            break;
    }
    

    【讨论】:

      【解决方案3】:

      如果你真的想减少代码,就像@Fabio 提到的那样,你可以使用字典。这可以设置为带有 ServiceName 和 Production 标志的复合键。

      类似:

      var claims = new Dictionary<(string, bool), Func<Task<ClaimResult>>>();
      claims.Add(("ARM", true), () => WebService<ARMProduction.WebServiceAWI>.GetClaim(claimParams, _environment.ARMUrl, 
              _environment.TrustOnlineUsername, _environment.TrustOnlinePassword, new ARMProduction.User()));
      claims.Add(("ARM", false), () => WebService<ARMDevelopment.WebServiceAWI>.GetClaim(claimParams, _environment.ARMUrl, 
              _environment.TrustOnlineUsername, _environment.TrustOnlinePassword, new ARMDevelopment.User()));
      var claimResult = await claims[(claimParams.ServiceName, _environment.Production)].Invoke();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-14
        • 1970-01-01
        • 2016-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多