使用代码克隆检测功能查找重复代码

代码克隆是非常相似的独立代码片段。在已开发一段时间的应用程序中,常会出现这种现象。克隆提高了更改应用程序的难度,因为你必须找到并更新多个片段。

Visual Studio Ultimate 或 Visual Studio Premium 可帮助你查找代码克隆,以便你进行重构。

你可以查找特定片段的克隆,也可以查找解决方案中的所有克隆。除了发现直接复制的片段外,克隆分析工具还可以找到变量和参数名称不同的片段,以及某些语句重新排列的片段。

代码克隆分析器可用于在整个 Visual Studio 解决方案中搜索 Visual C# 和 Visual Basic 项目中的重复代码。

高度匹配的代码克隆分析结果

查找特定代码片段的克隆

  1. 突出显示方法或 get/set 定义中的代码片段。

    说明说明

    你可以查找语句克隆,但不能查找字段、方法或属性签名等声明。

  2. 在片段的快捷菜单上,选择**“在解决方案中查找匹配的克隆”**。

当你想知道解决方案中是否已存在相似的方法或片段时,请使用此方法。

查找解决方案中的所有克隆

  • 在**“分析”菜单上,选择“分析解决方案是否有代码克隆”**。

当你审查代码时,此方法尤其有用。

说明说明

此命令不会扫描长度少于 10 个语句的方法。

结果按相似性顺序呈现。展开每个项可查看代码片段。

请注意,即使相似片段所使用的局部变量具有不同的名称,并且插入或删除了几个语句,也会被检测到。

比较克隆

  1. 在**“代码克隆结果”**窗口中,选择两个文件或包含两个文件的克隆组。

  2. 从快捷菜单中选择**“比较”**。

此功能使用的比较工具与比较源代码管理下的版本所使用的工具相同。如果要更改它,请从**“工具”菜单中选择“选项”。展开“源代码管理”“Visual Studio Team Foundation Server”。选择“配置用户工具”,然后选择“添加”**。

从分析中排除特定文件或方法

  1. 向定义了要排除的方法的 Visual Studio 项目中添加新 XML 文件。

    该文件是否属于该项目并不重要。它必须位于项目的顶层目录中。

  2. 将文件扩展名更改为 .codeclonesettings

  3. 编辑文件的内容,使其类似于以下示例。

    <CodeCloneSettings>
      <Exclusions>
        <!-- Add any combination of the following node types. -->
        <!-- Absolute or relative path names: -->
        <File>MyFile.cs</File>
        <!-- Filepaths may contain wildcards: -->
        <File>GeneratedFiles\*.cs</File>
        <!-- Namespace, Type, and FunctionName must be fully qualified: -->
        <Namespace>MyCompany.MyProject</Namespace>
        <Type>MyCompany.MyProject.MyClass1</Type>
        <FunctionName>MyCompany.MyProject.MyClass2.MyMethod</FunctionName>
        <!-- Names may contain wildcards: -->
        <Namespace>*.AnotherProject</Namespace>
        <Type>*.AnotherClass*</Type>
        <FunctionName>MyProject.*.AnotherMethod</FunctionName>
      </Exclusions>
    </CodeCloneSettings>      
    

查找哪些代码克隆?

代码克隆分析器将查找“在一定限制范围内”的克隆。

代码克隆通常是由于开发人员复制代码后又根据新位置进行改写而产生的。因此,最简单的做法是,考虑对克隆的更改达到何种程度以后分析器才会找不到克隆。在进行下列修改后,克隆仍可被识别。在每种情况下,此类修改的数量都有一定的限制:

  • 重命名标识符。

  • 插入和删除语句。

  • 重新排列语句。

哪些重复代码会找不到?

  • 系统不会比较类型声明。例如,你有两个字段声明组非常相似的类,系统不会将其报告为克隆。

    系统只会比较方法和属性定义中的语句。

  • **“分析解决方案是否有代码克隆”**不会在长度少于 10 个语句的方法中查找克隆。

    但是,你可以对较短的片段应用**“在解决方案中查找匹配的克隆”**。

  • 已更改标记超过 40% 的片段。

  • 如果项目包含 .codeclonesettings 文件,并且 .codeclonesettings 文件的 Exclusions 部分中指定了代码元素,则系统不会搜索该项目中定义的这些代码元素。

  • 生成的某些种类的代码:

    1. *.designer.cs, *.designer.vb

    2. InitializeComponent 方法

    但是,此方法不会自动应用于所有生成的代码。例如,使用文本模板时,你可能希望通过在 .codeclonesettings 文件中指定生成的文件来排除它们。

何时使用代码克隆分析

在以下情况中查找克隆通常有用:

  • **更新现有代码时。**修复 bug 或响应需求的变化时,一般首先会在需要更改的代码中查找位置。在进行更改之前,搜索该代码片段的克隆。如果发现克隆:

    1. 考虑是否需要对每个克隆进行相同的更改。

    2. 考虑这是否也是一个重构克隆代码的好机会,以便添加到共享方法或类中。

  • 体系结构清理。在每次迭代结束时,请使用“分析”菜单上的“分析解决方案是否有代码克隆”

  • **创建编码时。**编写新代码后,请使用该工具查找已存在的相似代码。

对大型代码库应用克隆分析

大型项目的完全独立的部分之间经常复制代码,而且经常复制到组织的不同部分。因此,你应当在尽可能大的代码库中查找克隆,而不是仅在你处理的当前解决方案中查找。

若要在源树间应用代码克隆分析器,请创建一个包含存储库中所有项目的解决方案。

提示提示

请记住,一个项目可包含在多个解决方案中。若要分析大量项目中是否有代码克隆,可以创建一个包含所有项目的解决方案。无需从通常借以访问项目的解决方案中移除项目。

生成的代码

代码克隆分析不适合与生成的代码一起使用。例如:

  • 由 T4 模板生成的代码。

    有关 T4 的更多信息,请参见 代码生成和 T4 文本模板

  • 从设计器生成的代码,例如 Silverlight 或 WPF 用户界面设计器。

从代码克隆分析中排除由 T4 模板生成的文件

  1. 将模板放在 Visual Studio 项目的一个子目录下。为其命名,例如 GeneratedFiles。

  2. 向项目中添加新的文本文件,将其名称和扩展名更改为 t4Exclusions.codeclonesettings

  3. 如下更改文件内容:

    <CodeCloneSettings>
      <Exclusions>
        <File>GeneratedFiles\*.cs</File>
      </Exclusions>
    </CodeCloneSettings>