简化长嵌套 if 语句工作流 C#
本文关键字:语句 工作流 if 嵌套 | 更新日期: 2023-09-27 17:55:30
该程序用于验证Excel行数据。如果 if 语句为 false,我需要将一条消息附加到字符串中,依此类推,用于 N 个 if 语句。这是行不通的,因为正如你所看到的,如果第一个 if 语句失败,我不会继续处理另一个 if 语句。同样在以后,我需要处理 100+ 列,所以我正在寻找一种方法来做到这一点。
有没有其他方法可以重写它,使其更具可读性且重复性更少?我知道我可以做一个巨人,如果(....&& ....)用于验证所有单元格和单个 if 语句以附加消息,但我想知道是否有另一种方法可以做到这一点。我想保留错误的顺序,但这并不那么重要。结果类似于"facilityID is invalid, daysOfTheWeek is invalid"
我也返回自定义 Pair 数据类型。
string facilityID, facilityDockDoorID, increment, hoursOfOperationId, updatedById, startTime, endTime, dockDoorServiceType, daysOfTheWeek;
facilityID = row[0];
facilityDockDoorID = row[1];
increment = row[2];
hoursOfOperationId = row[3];
updatedById = row[4];
startTime = row[5];
endTime = row[6];
dockDoorServiceType = row[7];
daysOfTheWeek = row[8];
string errorMessage = " is invalid";
if (IsInt(facilityID))
{
if (IsInt(facilityDockDoorID))
{
if (IsInt(increment))
{
if (IsInt(hoursOfOperationId))
{
if (IsInt(updatedById))
{
if (IsTime(startTime))
{
if (IsTime(endTime))
{
if (IsValidDockDoorServiceType(dockDoorServiceType))
{
if (IsValidDayOfTheWeek(daysOfTheWeek))
{
isDataValid.First = true;
}
else
{
isDataValid.Second += "daysOfTheWeek" + errorMessage + ",";
}
}
else
{
isDataValid.Second += "dockDoorServiceType" + errorMessage + ",";
}
}
else
{
isDataValid.Second += "endTime" + errorMessage + ",";
}
}
else
{
isDataValid.Second += "startTime" + errorMessage + ",";
}
}
else
{
isDataValid.Second += "updatedById" + errorMessage + ",";
}
}
else
{
isDataValid.Second += "hoursOfOperationId" + errorMessage + ",";
}
}
else
{
isDataValid.Second += "increment" + errorMessage + ",";
}
}
else
{
isDataValid.Second += "facilityDockDoorID" + errorMessage + ",";
}
}
else
{
isDataValid.Second = "facilityID" + errorMessage + ",";
}
return isDataValid;
}
如果你反
转if
语句并返回每个语句,你可以像这样扁平化你的代码。
if (!IsInt(facilityID))
{
isDataValid.Second = "facilityID" + errorMessage + ",";
return isDataValid;
}
if (!IsInt(facilityDockDoorID))
{
isDataValid.Second += "facilityDockDoorID" + errorMessage + ",";
return isDataValid;
}
if (!IsInt(increment))
{
isDataValid.Second += "increment" + errorMessage + ",";
return isDataValid;
}
if (!IsInt(hoursOfOperationId))
{
isDataValid.Second += "hoursOfOperationId" + errorMessage + ",";
return isDataValid;
}
if (!IsInt(updatedById))
{
isDataValid.Second += "updatedById" + errorMessage + ",";
return isDataValid;
}
if (!IsTime(startTime))
{
isDataValid.Second += "startTime" + errorMessage + ",";
return isDataValid;
}
if (!IsTime(endTime))
{
isDataValid.Second += "endTime" + errorMessage + ",";
return isDataValid;
}
if (!IsValidDockDoorServiceType(dockDoorServiceType))
{
isDataValid.Second += "dockDoorServiceType" + errorMessage + ",";
return isDataValid;
}
if (IsValidDayOfTheWeek(daysOfTheWeek))
{
isDataValid.First = true;
}
else
{
isDataValid.Second += "daysOfTheWeek" + errorMessage + ",";
}
return isDataValid;
但是,基于您连接到Second
的事实,您更有可能实际上想要类似的东西
if (!IsInt(facilityID))
isDataValid.Second = "facilityID" + errorMessage + ",";
if (!IsInt(facilityDockDoorID))
isDataValid.Second += "facilityDockDoorID" + errorMessage + ",";
if (!IsInt(increment))
isDataValid.Second += "increment" + errorMessage + ",";
if (!IsInt(hoursOfOperationId))
isDataValid.Second += "hoursOfOperationId" + errorMessage + ",";
if (!IsInt(updatedById))
isDataValid.Second += "updatedById" + errorMessage + ",";
if (!IsTime(startTime))
isDataValid.Second += "startTime" + errorMessage + ",";
if (!IsTime(endTime))
isDataValid.Second += "endTime" + errorMessage + ",";
if (!IsValidDockDoorServiceType(dockDoorServiceType))
isDataValid.Second += "dockDoorServiceType" + errorMessage + ",";
if (!IsValidDayOfTheWeek(daysOfTheWeek))
isDataValid.Second += "daysOfTheWeek" + errorMessage + ",";
isDataValid.First = isDataValid.Second.Length == 0;
return isDataValid;
请注意,我正在比较Second
的长度以确定是否发生了任何错误。
你可以反转if语句。例如:
if(!IsInt(facilityID))
{
isDataValid.Second = "facilityID" + errorMessage + ",";
}
if(!IsInt(facilityDockDoorID))
{
isDataValid.Second += "facilityDockDoorID" + errorMessage + ",";
}
您可以构建验证器函数的集合,例如:
List<Func<string[], StringBuilder, bool>> validators = new List<Func<string[], StringBuilder, bool>>();
validators.Add((row, logger) =>
{
string facilityID = row[0];
if(IsInt(facilityID))
{
logger.AppendLine("facilityID is invalid");
return false;
}
return true;
});
validators.Add((row, logger) =>
{
string increment = row[2];
if (IsInt(increment))
{
logger.AppendLine("increment is invalid");
return false;
}
return true;
});
. . .
然后,您可以像这样循环遍历所有内容:
StringBuilder log = new StringBuilder();
if(validators.Any(v => v(rows, log) == false))
{
return false;
}
else
{
return true;
}
isDataValid.Second = log.ToString();
通过这种方式,您可以将验证器逻辑分解为更小的块。这样可以避免嵌套if
语句。每个验证器负责选择要验证的数据,返回有效/无效bool
,并将任何消息记录到公共StringBuilder
。随着验证器列表的增长,您只需向集合添加新函数即可。
最好将架构与代码功能分开。这允许您在将来更改架构,而无需更改代码的其余部分。
public class SchemaItem
{
public int Index;
public string ColumnName;
public int ParsedValue;
public SchemaItem(int index, string columnName)
{
Index = index;
ColumnName = columnName;
}
}
public static Dictionary<int, SchemaItem> Schema = new Dictionary<int, SchemaItem>
{
{0, new SchemaItem(0, "facilityID")},
{1, new SchemaItem(1, "facilityDockDoorID")},
{2, new SchemaItem(2, "increment")},
{3, new SchemaItem(3, "hoursOfOperationId")},
{4, new SchemaItem(4, "updatedById")},
{5, new SchemaItem(5, "startTime")},
{6, new SchemaItem(6, "endTime")},
{7, new SchemaItem(7, "dockDoorServiceType")},
{8, new SchemaItem(8, "daysOfTheWeek")},
};
private static bool ParseIntAndOrWriteFailMessage(string[] row, StringBuilder logger, int index)
{
string cellContents = row[index];
string columnName = Schema[index].ColumnName;
int intContents = -1;
if (int.TryParse(cellContents, out intContents))
{
Schema[index].ParsedValue = intContents;
return true;
}
logger.AppendFormat("{0} is invalid,", columnName);
return false;
}
最后你会做:
StringBuilder logger = new StringBuilder();
foreach (var column in Schema.Select(pair => pair))
{
ParseIntAndOrWriteFailMessage(row, logger, column.Key);
}
// Parsed values are now stored in the Schema Dictionary (which probably could use a better name)