如何简化 switch 语句以降低圈复杂度

How to simplify a switch statement to reduce the cyclomatic complexity

我有一个很大的 switch 语句,其圈复杂度为 31,必须至少重构为 25。 这是错误:严重性代码描述项目文件行抑制状态抑制状态 错误 CA1502 'Worker.StartListening()' 的圈复杂度为 31。重写或重构方法以将复杂度降低到 25。

谢谢!

代码如下:

public void StartListening()
    {
        var consumerSettingsSection= this.configurationManager.GetSection<ConsumerSettingsSection>("appZ/consumer");
        foreach (var setting in consumerSettingsSection.QueueSettings)
        {
            var eventType = ConsumedEventType.NotSpecified;

            switch (setting.Name)
            {
                case "A":
                    eventType = ConsumedEventType.A;
                    break;

                case "B":
                    eventType = ConsumedEventType.B;
                    break;

                case "C":
                    eventType = ConsumedEventType.C;
                    break;

                case "D":
                    eventType = ConsumedEventType.D;
                    break;

                case "E":
                    eventType = ConsumedEventType.E;
                    break;

                case "F":
                    eventType = ConsumedEventType.F;
                    break;

                case "G":
                    eventType = ConsumedEventType.G;
                    break;

                case "H":
                    eventType = ConsumedEventType.H;
                    break;

                case "I":
                    eventType = ConsumedEventType.I;
                    break;

                case "J":
                    eventType = ConsumedEventType.J;
                    break;

                case "K":
                    eventType = ConsumedEventType.K;
                    break;

                case "L":
                    eventType = ConsumedEventType.L;
                    break;

                default:
                    eventType = ConsumedEventType.NotSpecified;
                    break;
            }

            var consumer = new ChannelConsumer(setting, eventType);
            consumer.MessageConsumed += this.Consumer_MessageConsumed;
            consumer.StartConsuming();
        }
    }

使用 Dictionary<string, ConsumedEventType>:

var d = new Dictionary<string, ConsumedEventType>() 
{
    { "A", ConsumedEventType.A },
    { "B", ConsumedEventType.B },
    { "C", ConsumedEventType.C },
    ...
}

现在获取适合您的实际值 settings.Name:

ConsumedEventType type;
var type = !d.ContainsKey(settings.Name)
    ConsumedEventType.NotSpecified : 
    d[setting.sName];

您可以尝试使用 Enum.TryParse 方法来简化您的代码:

 if (Enum.TryParse(setting.Name, true, out eventType)) 
     return eventType;
 else
     return ConsumedEventType.NotSpecified;

可以将setting.Name字符串解析为ConsumedEventType,使用解析后的值,否则为returnConsumedEventType.NotSpecified值。

它比维护值列表更容易。根据您上面的代码,您可以编写类似的东西

foreach (var setting in consumerSettingsSection.QueueSettings)
{
    var eventType = ConsumedEventType.NotSpecified;
    if (Enum.TryParse(setting.Name, true, out ConsumedEventType parsedEvent))
    {
         eventType = parsedEvent;
    }
    //rest of code
}

或者更简单

if (!Enum.TryParse(setting.Name, true, out ConsumedEventType eventType))
{
    eventType = ConsumedEventType.NotSpecified;
}

请记住,从 C# 7

开始支持内联 out 变量