如何简化 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
变量
我有一个很大的 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
变量