0

我有一个嵌套的 foreach 循环,我想知道哪种方法是根据 c# 中的 if 条件跳过记录的最佳方法。

以下是我的解决方案,如果有任何改进或建议,请告诉我。

foreach (var ospMap in sourceSpecificMaps)
{
    foreach (var idMapSensorId in ospMap.SensorIds)
    {
        try
        {
            if (string.IsNullOrEmpty(idMapSensorId.SourceId))
            {
                throw new Exception($"SourceId couldn't be found in the { idMapSensorId.SensorId } sensor. The sensor is being skiped.");
            }
            _ospIdMapDictionary[GenCacheId(sourceId, idMapSensorId.SensorId)] = ospMap;
       }
       catch (Exception)
       {
            // We continue through the loop
            continue;
       }  
    }
}
4

5 回答 5

1

您正在使用异常来控制逻辑流,这通常是一个坏主意。除非你真的要对那个异常做些什么,否则摆脱它,把 continue 放在 if 语句中。

于 2019-11-05T15:54:02.533 回答
1

如果逻辑过程不需要它,我认为你可以删除你的 try catch,

然后你将有这样的代码:

foreach (var ospMap in sourceSpecificMaps)
{
    foreach (var idMapSensorId in ospMap.SensorIds)
    {

            if (string.IsNullOrEmpty(idMapSensorId.SourceId))
            {
                 continue; // SourceId couldn't be found in the { idMapSensorId.SensorId } sensor. The sensor is being skiped
            }
            _ospIdMapDictionary[GenCacheId(sourceId, idMapSensorId.SensorId)] = ospMap;

    }
}
于 2019-11-05T15:54:49.183 回答
1

使用这样的异常既慢(异常非常慢)又糟糕的做法。如果您想跳过,只需使用继续。

foreach (var ospMap in sourceSpecificMaps)
{
  foreach (var idMapSensorId in ospMap.SensorIds)
  {
    if (string.IsNullOrEmpty(idMapSensorId.SourceId))
    {
      continue; // TODO: Log the follwoing ?  SourceId couldn't be found in the { idMapSensorId.SensorId } sensor. The sensor is being skiped
    }
    _ospIdMapDictionary[GenCacheId(sourceId, idMapSensorId.SensorId)] = ospMap;
  }

}
于 2019-11-05T15:55:06.257 回答
1

使用 linq,您可以执行以下操作:

var list = outerList.SelectMany(x => x.TheInnerList).Where(n => !string.IsNullOrEmpty(n.Id));

我认为根据初始条件迭代这些元素是完成这项工作的最干净的方法

于 2019-11-05T16:03:46.017 回答
1

你想要的是这样的:

foreach (var ospMap in sourceSpecificMaps)
{
    foreach (var idMapSensorId in ospMap.SensorIds)
    {
        if (string.IsNullOrEmpty(idMapSensorId.SourceId))
        {
            // SourceId couldn't be found in the sensor. The sensor is being skipped.
            continue;
        }
        _ospIdMapDictionary[GenCacheId(sourceId, idMapSensorId.SensorId)] = ospMap; 
    }
}

正如上面每个人都提到的,除非您抛出异常并且正确处理由异常引起的错误条件的唯一方法是在循环之外的某个地方捕获,否则不要将异常用于控制流。与简单的条件测试相比,它们极其缓慢且资源密集。尤其是在循环中,如果您获得大量空的 sourceId,这种方法可能会严重影响您的应用程序性能。

在您的示例中,正如其他人所说,您实际上并没有“处理”异常。您只是忽略它并在“if”语句之后跳过循环的剩余主体。上面的代码产生了完全相同的行为。

于 2019-11-05T16:05:06.090 回答