public class Human : Mortal
{
public Mortal FindHuman(string name)
{
Mortal mortal = null;
foreach (Mortal friend in friends)
{
if (String.Compare(friend.Name, name, false) == 0)
{
Console.WriteLine("Found a Human: " + friend.Name);
mortal = friend;
break;
}
}
return mortal;
}
} So far so good. But now, let’s do something incredibly dangerous. We’re going to make a copy of this Human class and perform a search and replace, “Human” for “Martian”…
public class Martian : Mortal
{
public Mortal FindMartian(string name)
{
Mortal mortal = null;
foreach (Mortal friend in friends)
{
if (String.Compare(friend.Name, name, false) == 0)
{
Console.WriteLine("Found a Martian: " + friend.Name);
mortal = friend;
break;
}
}
return mortal;
}
}
But let’s continue to change the code. Let’s introduce a few local variables, rename “mortal” to “myFavoriteMartian”, remove the unnecessary curly braces around the if-block, and change case-sensitivity of the String.Compare call so it ignores case (as one might expect with Martian names)…
public class Martian : Mortal
{
public Mortal FindMartian(string name)
{
Mortal myFavoriteMartian = null;
bool ignoreCase = true;
string msg = "Found a Martian: ";
foreach (Mortal friend in friends)
if (String.Compare(friend.Name, name, ignoreCase) == 0)
{
Console.WriteLine(msg + friend.Name);
myFavoriteMartian = friend;
break;
}
return myFavoriteMartian;
}
}
And now we have some code that is functionally equivalent, but structurally distinct. Can CodeRush find this? It can, providing we drop the Analysis Level down to 2, so the detection engine can see this smaller code block (the default level is set to 3, which is a slightly larger block):

Here’s what the code looks like inside Visual Studio:

On the left of the gutter in each view, you see a thin purple vertical bar. This means duplicate code exists elsewhere. Also, in the bottom right, the “!!” icon signals CodeRush has detected duplicates inside the solution. If you hover over the icon in the bottom right, a hint appears to explain the status.

You can click the icon to see a summary of all duplicate clusters found inside the new Duplicate Code tool window. In this case, our simple example, only one cluster is found:

On the left is a list of all clusters found, sorted by redundancy (the total amount of redundant code that could be removed if consolidated). Note that because we are sorting by redundancy, it’s possible for a very small block of code (duplicated many times) to appear above a very large duplicate block of code (that only appears twice).
On the right is a preview of the duplicate code. You can double-click any duplicate code preview to be taken directly to that location. When you do this, CodeRush immediately presents the consolidation hint, which looks like this:

Notice the mouse is positioned right over the “Next duplicate block” button, in case you want to navigate and compare the blocks. This might be useful when it’s time to consolidate. The block you consolidate from determines the structure of the consolidated block. So let’s consolidate from the FindMartian method. Click the “Next duplicate block” button, then move the mouse over the “to the base class” consolidation option. You’ll see a preview hint that looks like this:

Notice the parameters to FindMartianExtracted – CodeRush takes the code that differs between the blocks and turns them into parameters. Press Enter to apply the consolidation. The target picker will appear letting you select the location of the consolidated method.

The target picker shows the block of code that will be inserted. It’s based upon the structure of the method where we initiated the consolidation (FindMartian). Let’s press Escape to cancel and back out of this, and then see what happens when we initiate consolidation from the other duplicate…

Now consolidate to the base class Mortal. We’ll see the target picker. Notice how the FindHumanExtracted consolidated code in the preview below differs from the FindMartianExtracted consolidated code in the preview shown two screen shots above.

Just use the up/down arrow buttons to select a location and press Enter to accept it. Now we’re left with a small task of coming up with good names for the consolidated method and its parameters.

And the calling code is simplified:

And that’s it (for a simple consolidation example)!
An Even Bigger Example
But what happens when the project is much bigger? The good news is, that the detection scales well for large solutions, taking only seconds (at most a few minutes) to scan thousands of files for duplicates at the default settings (Analysis Level set to 3). Let’s take a look at DDC with the source to Umbraco.
Here’s cluster #4 selected. The Lowest and Highest methods inside the ExsltMath class:

Nearly identical blocks of code. However note the real difference is in the operator used to compare t against min (and max). On the left you have “t < min”, and on the right you have “t > max”. Can CodeRush consolidate this duplicate? It can. Here’s the preview hint:

And after consolidation (and renaming the method, the “min” local, and the “func” parameter), I get this:

And now the quality of the code is much higher than it was before.
Remember, CodeRush has the fastest duplicate code detection available for .NET. It works in the background and shows when you’re working inside a method that is cloned. Consolidation is based on the structure of the method you start from. While CodeRush can consolidate many kinds of duplicate blocks, not all duplicate blocks can be consolidated automatically (trust me, this is an incredibly challenging problem to solve). But we’re working on making the consolidation engine even smarter and even more extensive as we approach the 12.1 release (and we expect to blow your mind again with that one).
Do me a favor, kids: Tell every developer you know about CodeRush’s Duplicate Detection and Consolidation. DDC is truly revolutionary; help us spread the word.