有没有办法重构 C# 独有的 switch 语句?
Is there a way to refactor a switch statement that is unique to C#?
我是 C# (.NET 4.0) 项目的新员工,但我有 C/C++ 背景。我被指示 "generally improve our product" 并遇到了一个甚至 1000 行长的方法,它主要由一个包含 15 个案例的 switch 语句组成,每个案例大约有 60 行代码。
在这次演出之前,我会保留相同的通用格式,但会提取 15 个函数,然后根据需要研究如何 share/point 到本地 variables/class 数据成员。但是,我现在可以使用各种神秘的新工具,而且我无法摆脱一种 "C# smart" 方法来解决这个问题的感觉。
有没有办法在 C#(4.0) 中重构这个在 C++ 中无法完成的 switch 语句?
编辑: 这是代码的净化和总结形式:
private void DeviceRequest(List<OpRequest> currentOp, double adjTime) {
//local variables
while (/*condition*/)
{
//Some setup
//Some initialization
try
{
switch (OperationType)
{
case Setup:
//Message header setup through 'if-else' statements
//Message sending
//Many nested 'if' checks, a few less 'else's
break;
case Initiate:
//Message header setup through 'if-else' statements
//Message sending
//Many nested 'if' checks, a few less 'else's
break;
case Acquire:
//Message header setup through 'if-else' statements
//Message sending
//Many nested 'if' checks, a few less 'else's
break;
case Measure:
//Message header setup through 'if-else' statements
//Message sending
//Many nested 'if' checks, a few less 'else's
break;
case Reset:
//Message header setup through 'if-else' statements
//Message sending
//Many nested 'if' checks, a few less 'else's
break;
//12 more cases, all fairly similar.
}
}
catch (RunTimeError err)
{
//A few lines of code
}
finally
{
//Objective measure of time passage
}
}
}
enum
上的 switch
通常可以替换为 Dictionary
动作。为了为此做好准备,每个动作都必须处理相同的输入。
如果您可以将代码重构为 15 个具有相同签名的方法的集合,则可以将它们放入 Dictionary<OpRequest,DelegateType>
,其中 DelegateType
是具有您的方法签名的委托。
例如,如果 15 个方法中的每一个都具有以下签名
private void SetupAction(double adjTime) {
...
}
void InitiateAction(double adjTime) {
...
}
你可以建立一个动作字典
private readonly IDictionary<OpRequest,Action<double>> OpActions = new Dictionary<OpRequest,Action<double>> {
{OperationType.Setup, SetupAction}
, {OperationType.Initiate, InitiateAction}
, ... // and so on
};
有了这个字典,您可以按如下方式重写循环:
while (/*condition*/) {
//Some setup
//Some initialization
try {
Action<double> action;
if (OpActions.TryGetValue(opType, out action)) {
action(adjTime);
} else {
... // Report an error: unknown OpRequest
}
} catch (RunTimeError err) {
... //A few lines of code
}
finally {
... //Objective measure of time passage
}
}
我是 C# (.NET 4.0) 项目的新员工,但我有 C/C++ 背景。我被指示 "generally improve our product" 并遇到了一个甚至 1000 行长的方法,它主要由一个包含 15 个案例的 switch 语句组成,每个案例大约有 60 行代码。
在这次演出之前,我会保留相同的通用格式,但会提取 15 个函数,然后根据需要研究如何 share/point 到本地 variables/class 数据成员。但是,我现在可以使用各种神秘的新工具,而且我无法摆脱一种 "C# smart" 方法来解决这个问题的感觉。
有没有办法在 C#(4.0) 中重构这个在 C++ 中无法完成的 switch 语句?
编辑: 这是代码的净化和总结形式:
private void DeviceRequest(List<OpRequest> currentOp, double adjTime) {
//local variables
while (/*condition*/)
{
//Some setup
//Some initialization
try
{
switch (OperationType)
{
case Setup:
//Message header setup through 'if-else' statements
//Message sending
//Many nested 'if' checks, a few less 'else's
break;
case Initiate:
//Message header setup through 'if-else' statements
//Message sending
//Many nested 'if' checks, a few less 'else's
break;
case Acquire:
//Message header setup through 'if-else' statements
//Message sending
//Many nested 'if' checks, a few less 'else's
break;
case Measure:
//Message header setup through 'if-else' statements
//Message sending
//Many nested 'if' checks, a few less 'else's
break;
case Reset:
//Message header setup through 'if-else' statements
//Message sending
//Many nested 'if' checks, a few less 'else's
break;
//12 more cases, all fairly similar.
}
}
catch (RunTimeError err)
{
//A few lines of code
}
finally
{
//Objective measure of time passage
}
}
}
enum
上的 switch
通常可以替换为 Dictionary
动作。为了为此做好准备,每个动作都必须处理相同的输入。
如果您可以将代码重构为 15 个具有相同签名的方法的集合,则可以将它们放入 Dictionary<OpRequest,DelegateType>
,其中 DelegateType
是具有您的方法签名的委托。
例如,如果 15 个方法中的每一个都具有以下签名
private void SetupAction(double adjTime) {
...
}
void InitiateAction(double adjTime) {
...
}
你可以建立一个动作字典
private readonly IDictionary<OpRequest,Action<double>> OpActions = new Dictionary<OpRequest,Action<double>> {
{OperationType.Setup, SetupAction}
, {OperationType.Initiate, InitiateAction}
, ... // and so on
};
有了这个字典,您可以按如下方式重写循环:
while (/*condition*/) {
//Some setup
//Some initialization
try {
Action<double> action;
if (OpActions.TryGetValue(opType, out action)) {
action(adjTime);
} else {
... // Report an error: unknown OpRequest
}
} catch (RunTimeError err) {
... //A few lines of code
}
finally {
... //Objective measure of time passage
}
}