有没有一种标准的方法来计算C#中的语句

时间:2010-02-28 03:12:43

标签: c# metrics code-metrics

我正在查看除代码行之外的一些代码长度指标。 Source Monitor报告的内容是语句。这似乎是一件值得知道的事情,但Source Monitor计算某些东西的方式似乎不直观。例如,for语句是一个语句,即使它包含变量定义,条件和增量语句。如果方法调用嵌套在另一个方法的参数列表中,则整个事物被认为是一个语句。

是否有一种标准的方式来计算报表,并且是他们管理此类事情的规则?

4 个答案:

答案 0 :(得分:7)

指标的第一条规则是“小心你衡量的东西”。你要求一份陈述,这就是你要得到的。如你所知,这个数字可能实际上并不相关。

如果您对其他测量方法感兴趣,例如“复杂”代码的方式,请考虑查看其他代码指标,例如周期性复杂性。

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

更新:回复:您的评论

我同意“做太多”是一个有趣的指标。我的经验法则是,一个语句应该有一个副作用(通常是“局部”副作用,如改变局部变量,但有时是可见的副作用,如写入文件),因此“语句数”应该是粗略的与该方法在副作用数量方面“做”的程度相关。

在实践中,当然没有人的代码(包括我自己的代码)实际上始终符合该条形码。您可以考虑“方法正在做多少”的度量标准,不仅可以计算语句,还可以计算方法调用。

要真正回答你的问题:我不知道有任何行业标准来规定“声明数量”是什么。 C#规范无疑定义了词条的“声明”,但当然你必须做一些解释来计算。例如:

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

M中有多少陈述?好吧,M的主体由一个声明组成,一个试试 - 最终。答案是这样的吗? try的主体包含一个语句,一个“if”语句。 “if”的结果包含一个语句 - 记住,块是一个语句。该块包含两个语句。最后包含一个声明。 catch块不包含任何语句 - 一个catch 不是一个语句,在词法上 - 但它肯定与该方法的操作高度相关!

那么完全有多少陈述?人们可以为1到6之间的任何数字做出合理的判断,这取决于你是否将块计为“真实”语句,是否将子语句视为父语句之外的其他数字,等等。没有标准机构来规范我所知道的这个问题的答案。

答案 1 :(得分:5)

你最接近“什么是陈述”的正式定义将是C# specification本身。祝你好运,确定特定工具的测量是否与您对规范的阅读一致。

鉴于指标最好用作指南以更好/更差的代码,而不是严格的公式,该工具使用的确切定义是否会产生很大的差异?

如果我有三种方法,“语句长度”分别为2500,1500和150,我知道我将首先检查哪种方法;另一个工具可能报告2480,1620和174并不太重要。

我见过的衡量指标的最佳工具之一是NDepend,但我再也不能100%确定它使用的是什么定义。根据网站NDepend has 82 separate metrics,包括Number of instructionsCyclomatic Complexity

答案 2 :(得分:3)

C# Metrics Tool通过使用精确的C#BNF语言定义来定义要计数的内容(“语句”,“操作数”)等。 (实际上,它根据完整的C#语法精确地解析代码,然后通过遍历解析树来计算结构度量; SLOC计数它是按照您期望的方式通过countline行获得的。)

你可能仍然认为这样的定义不直观(语法很少),但它们是精确的。但是,我同意其他海报的确切措施并不像一个代码块相对于另一个代码的相对价值那么重要。值“173.92”的复杂性本身并不是很有用;与另一个复杂度值“81.02”相比,我们可以说有一个很好的迹象表明第一个比第二个更复杂,这足以引起人们的关注。

我认为指标在趋势中也很有用;如果上周这个代码是“81.02”复杂,本周广告它是“173.92”,我应该想知道为什么会发生这部分代码呢?

您可能还会考虑结构度量(例如,Cyclomatic)与SLOC的比率作为“做太多”的指示,或者至少表示编写的代码太过密集而无法理解

答案 3 :(得分:1)

一个简单的指标是只计算令牌之间的标点符号(;,.)(以避免字符串,注释或数字中的标点符号)。因此,for (x = 0, y = 1; x < foo.Count; x++, y++) bar[y] = foo[x];将计为6。