Running identical code on 2 objects
<p>I have a test script that does something to one object then the same thing to a second object. This continues for quite a while. With so much predictable repetition that it seems ripe for automation but I can't figure out how. I wouldn't care so much except with so much repetition, it's easy to overlook using the wrong variable (ie: stagingXyz when prodXyz was intended.)</p>

<p><strong>The details below are irrelevant. What's important is the pattern.</strong></p>

<pre><code>var stagingDbs = cleanupDbs(stagingServer.Databases);
var prodDbs = cleanupDbs(prodServer.Databases);

printDiff(stagingDbs, prodDbs, "Databases mis-matched");

foreach (var db in stagingDbs.Intersect(prodDbs)) {
    var stagingDb = stagingServer.Databases[db];
    var prodDb = prodServer.Databases[db];

    var stagingTables = cleanupTables(stagingDb.Tables);
    var prodTables = cleanupTables(prodDb.Tables);

    printDiff(stagingTables, prodTables, "Tables mis-matched on " + db);

    foreach (var table in stagingTables.Intersect(prodTables)) {
        var stagingTable = stagingDb.Tables[table];
        var prodTable = prodDb.Tables[table];

        var matchedColumns = stagingColumns.Intersect(prodColumns);

        var stagingTableColumns = stagingTable.Columns
            .Cast&lt;Column&gt;()
            .Where(c =&gt; matchedColumns.Contains(c.Name))
            .Select(c =&gt; formatColumn(c));
        var prodTableColumns = prodTable.Columns
            .Cast&lt;Column&gt;()
            .Where(c =&gt; matchedColumns.Contains(c.Name))
            .Select(c =&gt; formatColumn(c));
        printDiff(stagingTableColumns, prodTableColumns,
            "Columns mis-matched");
    }
}
</code></pre>

<p>I don't want to go through, for instance, replacing this</p>

<pre><code>        var stagingTableColumns = stagingTable.Columns
            .Cast&lt;Column&gt;()
            .Where(c =&gt; matchedColumns.Contains(c.Name))
            .Select(c =&gt; formatColumn(c));
        var prodTableColumns = prodTable.Columns
            .Cast&lt;Column&gt;()
            .Where(c =&gt; matchedColumns.Contains(c.Name))
            .Select(c =&gt; formatColumn(c));
</code></pre>

<p>with this</p>

<pre><code>        var stagingTableColumns = doStuff(stagingTable, matchedColumns);
        var prodTableColumns = doStuff(prodTable, matchedColumns);
</code></pre>

<p>because I have to make sure everything in the 1st line is <code>stagingXyz</code> and the 2nd line is <code>prodXyz</code>. Not so bad for 1 line but the test script is huge and only ever does one of these 2 things:</p>

<ul>
<li>foo(stagingXyz); foo(prodXyz);</li>
<li>bar(stagingXyz, prodXyz);</li>
</ul>

<p>Similarly, wrapping with these items in an array and having <code>doStuff[0]; doStuff[1];</code> is subject to the same easy typo error only a typo with 0 vs. 1 will be even harder to spot at a glance.</p>

<p>I thought about making 2 container objects (one for staging, one for prod) and putting these 2 objects in a collection but I fear this will lead to a bazillion tiny loops that will be very hard to maintain.</p>

<p>Is there anyway to simplify this and still have it be readable and maintainable?</p>
