>
>
>
V3139. Two or more case-branches perfor…


V3139. Two or more case-branches perform the same actions.

Анализатор обнаружил ситуацию, когда в операторе switch разные метки case содержат одинаковые фрагменты кода. Часто это свидетельствует об избыточном коде, который можно улучшить объединением меток. Но нередко одинаковые фрагменты кода могут быть причиной copy-paste программирования и являться настоящими ошибками.

Рассмотрим пример с избыточным кодом:

switch (switcher) 
{
  case 0: Console.Write("0"); return;
  case 1: Console.Write("0"); return;
  default: Console.Write("default"); return;
}

Действия для нескольких значений 'switcher' действительно могут быть одинаковыми, поэтому код можно написать более компактно:

switch (switcher) 
{
  case 0:
  case 1: Console.Write("0"); return;
  default: Console.Write("default"); return;
}

Если вы используете 'case expression', то объединить такие выражения под одно условие у вас не получится:

private static void ShowCollectionInformation(object coll, bool cond)
{
  switch (coll)
  {
    case Array arr:
      if(cond)
      {
        Console.WriteLine (arr.ToString());
      }
      break;
    case IEnumerable<int> arr:
      if(cond)
      {
        Console.WriteLine (arr.ToString());
      }
      break;
   }
}

В таком случае, вы можете вынести общий код в метод, что облегчит дальнейшее редактирование и отладку.

Теперь, рассмотрим пример из реального приложения, где разработчик допустил ошибку:

switch (status.BuildStatus)
{
  case IntegrationStatus.Success:
    snapshot.Status = ItemBuildStatus.CompletedSuccess;
    break;
  case IntegrationStatus.Exception:
  case IntegrationStatus.Failure:
    snapshot.Status = ItemBuildStatus.CompletedSuccess;
    break;
}

В присвоение статуса попала ошибка: у перечисления 'ItemBuildStatus' есть элемент 'CompletedFailed', который следовало присвоить в случае ошибки или исключения.

Исправленный код:

switch (status.BuildStatus)
{
  case IntegrationStatus.Success:
    snapshot.Status = ItemBuildStatus.CompletedSuccess;
    break;
  case IntegrationStatus.Exception:
  case IntegrationStatus.Failure:
    snapshot.Status = ItemBuildStatus. CompletedFailed;
    break;
}

Взгляните на примеры ошибок, обнаруженных с помощью диагностики V3139.