Just chatting yesterday about quick wins in code reviews and the subject of de-duping code came up. Even recently I was in a project where two of us implemented the same checking logic at different tiers of the application (replace that with layers if you're into onion architectures). Something that is able to detect clone code would be incredibly useful...... well, it turns out there is a codeplex project: 'Clone Detective' that does just that (thanks to Rupert for putting me onto this). Internally it tokenizes your code, and matches the patterns - allowing you to quickly find repeating sections that are possibly candidates for refactoring even if the local names are different. The tool is available here, and I'd recommend watching the 10 minute video.

I think it does a great job of finding dupe code - it won't pick out small numbers of lines, for example common foreach loops, so is reasonably noise free and it's not looking at the functionality of the code. This does mean if your code differs by one line you may not match the rest of that block - (which makes perfect sense if that one line is consequential). For example - in the following, the block of recognised code stops at 'purple monkey dishwasher' and the remaining 'matching code' is not matched. This isn't by any means a criticism - I still think this is still a very cool tool.

A documented dependancy on conQAT means you will need to install a Java Virtual machine and configure the Java Home Directory - currently my install is looking at 'C:\Program Files\Java\jdk1.6.0_07'. It also appears to reset your DevEnv settings - so definately worth exporting and re-importing them after. It also has a great add-in which looks exactly like Solution explorer, but shows the number of dupes in each file. As they might say in some camps: 'Great Job' and 'Im super excited to be able to use this' ;)

public class CrazyAlgorithm
{
  public int someOtherAlgorithm(int number)
  {
  
   for (int j = 0; j < 10; j++)
   {
    int i = j * 10;
    number = number + i;
    number = 0;
    Console.WriteLine(number);
   
    using (MemoryStream ms = new MemoryStream())
    {
     byte[] y = BitConverter.GetBytes(number);
     foreach (byte c in y)
     {
      ms.WriteByte(c);
      ms.Position++;
      }
    
     number = y.Rank;
     number++;
    
     number = number + 1;
     }
    }
  
  
   return number;
   }
  }
public class SomeClass
{
 
  static int someOtherAlgorithm(int start)
  {
  
   int result = 0;
  
   for (int i = 0; i < 10; i++)
   {
    int j = i * 10;
    result = result + j;
    result = 0;
    Console.WriteLine(result);
    using (MemoryStream ms = new MemoryStream())
    {
     byte[] x = BitConverter.GetBytes(result);
     foreach (byte b in x)
     {
      ms.WriteByte(b);
      ms.Position++;
      }
    
     Console.WriteLine("Purple Monkey Dishwasher");
    
     result = x.Rank;
     result++;
     result = result + 1;
     }
    }
  
   return result;
   }
  }