Есть ли стандартный способ подсчета операторов в C # - PullRequest
3 голосов
/ 28 февраля 2010

Я смотрел на некоторые показатели длины кода, кроме строк кода. То, что сообщает Source Monitor, - это заявления. Это казалось ценным, но знать, как Source Monitor считал некоторые вещи, казалось не интуитивным. Например, оператор for является одним оператором, даже если он содержит определение переменной, условие и оператор приращения. И если вызов метода вложен в список аргументов другого метода, все считается одним утверждением.

Существует ли стандартный способ подсчета утверждений и регулируют ли их правила такие вещи?

Ответы [ 4 ]

7 голосов
/ 28 февраля 2010

Первое правило метрик - «будьте осторожны с тем, что вы измеряете». Вы просите подсчет утверждений, вот что вы получите. Как вы заметили, эта цифра, возможно, не соответствует действительности.

Если вас интересуют другие меры, например, насколько «сложный» код, рассмотрите другие метрики кода, например, циклометрическую сложность.

http://en.wikipedia.org/wiki/Cyclomatic_complexity

ОБНОВЛЕНИЕ: Re: ваш комментарий

Я согласен, что "делать слишком много" - интересная метрика. Мое эмпирическое правило заключается в том, что один оператор должен иметь один побочный эффект (обычно это «локальный» побочный эффект, такой как изменение локальной переменной, но иногда видимый побочный эффект, такой как запись в файл), и поэтому «количество операторов» должно быть примерно коррелирует с тем, сколько метод «делает» с точки зрения количества побочных эффектов.

На практике, конечно, никто, включая мой собственный код, фактически не встречает эту планку все время. Вы могли бы рассмотреть метрику для «того, сколько метод делает», чтобы посчитать не только операторы, но и, скажем, вызовы метода.

На самом деле, чтобы ответить на ваш вопрос: я не знаю ни одного отраслевого стандарта, который бы определял, что такое «количество утверждений». Спецификация C # определенно определяет, что такое «оператор», но, конечно, вам нужно сделать некоторую интерпретацию для подсчета. Например:

  void M()
  {
    try
    {
      if (blah)
      {
        Frob();
        Blob();
      }
    }
    catch(Exception ex)
    { /* eat it */ }
    finally
    {
      Grob();
    }
  }

Сколько утверждений в М? Ну, тело M состоит из одного утверждения, try-catch-finally. Так ответ один? Тело try содержит один оператор, оператор if. Следствие «если» содержит одно утверждение - помните, блок - это утверждение. Блок содержит два оператора. Наконец, содержит одно утверждение. Блок catch не содержит операторов - блок catch block не является оператором , лексически, но он, безусловно, очень важен для работы метода!

Так сколько всего это утверждений? Можно обоснованно обосновать любое число от одного до шести, в зависимости от того, считаете ли вы блоки «реальными» операторами, считаете ли вы дочерние операторы дополнением к их родительскому утверждению или нет, и так далее. Нет органа по стандартизации, который бы регулировал ответ на этот вопрос, о котором я знаю.

5 голосов
/ 28 февраля 2010

Наиболее близким к формальному определению «что такое утверждение» может быть сама спецификация C # . Удачи вам в определении того, соответствует ли измерение конкретного инструмента вашему чтению спецификации.

Учитывая, что метрики лучше всего использовать как руководство для лучшего / худшего кода, а не строгую формулу, имеет ли точное определение, используемое инструментом, большую разницу?

Если у меня есть три метода с «длинами операторов» 2500, 1500 и 150, я знаю, какой метод я рассмотрю первым; что другой инструмент может сообщать о 2480, 1620 и 174, не так уж важно.

Один из лучших инструментов, которые я видел для измерения метрик, - это NDepend , хотя, опять же, я не уверен на 100%, какие определения он использует. По данным сайта, NDepend имеет 82 отдельных показателя , в том числе Количество инструкций и Цикломатическая сложность .

3 голосов
/ 28 февраля 2010

C # Metrics Tool определяет подсчитываемые вещи («операторы», «операнды») и т. Д., Используя точное определение языка C # BNF. (Фактически, он точно анализирует код в соответствии с полной грамматикой C #, а затем вычисляет структурные метрики, обходя дерево разбора; счетчик SLOC получает по линиям линии отсчета, как и следовало ожидать).

Вы все еще можете утверждать, что такое определение оно не интуитивно (грамматики редко бывают), но они точны. Я согласен с другими постерами здесь, однако, что точная мера не так важна, как относительное значение, которое один блок кода имеет по отношению к другому. Значение сложности «173,92» само по себе не очень полезно; По сравнению с другим значением сложности «81,02», можно сказать, что есть хороший признак того, что первый более сложный, чем второй, и этого достаточно, чтобы обеспечить фокусировку внимания.

Я думаю, что метрики также полезны в тренде; если на прошлой неделе этот код был "81.02" сложным, а на этой неделе - "173.92", я должен задаться вопросом, почему все это происходит в этой части кода?

Вы также можете рассматривать отношение структурной метрики (например, Cyclomatic) к SLOC как указание на «слишком много работы» или, по крайней мере, указание на написание кода, который слишком плотен для понимания

1 голос
/ 28 февраля 2010

Одной простой метрикой является подсчет знаков препинания (;, ,, .) между токенами (во избежание их появления в строках, комментариях или числах). Таким образом, for (x = 0, y = 1; x < foo.Count; x++, y++) bar[y] = foo[x]; будет считаться 6.

...