Find abstraction for classes which represent tables with differnt amount of colums (based on DataTables) I have a lot of classes which are principal equal, but they consist small differences so that I can´t abstract then very well.

The classes represent different kinds of DataTables. Every Class has two important methods which every "table-class" has. Here a abstracted example:

internal class FooTable
{
    internal static DataTable CreateTable() 
    {
        using (DataTable fooTable = new DataTable("fooTable"))
        {
            // number and content of rows are different from table to table.
            fooTable.Columns.Add("ColFoo");
            fooTable.Columns.Add("ColBar");
            fooTable.Columns.Add("ColSomethingElse");

            AddRow(fooTable, "ValueA", "ValueB", "ValueC");
            AddRow(fooTable, "ValueD", "ValueE", "ValueF");
            // ... more rows ...

            return fooTable;
        }
    }

    private static void AddRow(
        DataTable table,
        string ColFoo,
        string ColBar,
        string ColSomethingElse)
    {
        DataRow dataRow = table.NewRow();

        dataRow["ColFoo"] = ColFoo;
        dataRow["ColBar"] = ColBar;
        dataRow["ColSomethingElse"] = ColSomethingElse;

        table.Rows.Add(dataRow);
    }
}


The differences between the tables are the number of columns and the datatyp of column content. With this implementation I can´t use abstract classes, because of the different amount of columns. The names of the columns are also redundant in code.

Finally I think about the use of params to solve the problem with different amount of columns, but I’m not sure how to make a good implementation other AddRow-methode.

private static void AddRow(DataTable table, params object[] values)
{       
    ... 
}


So did anyone know a better way to implement this? I'm sure there is a better way.
I can think of trying something like this.

interface ICount
{
  int count();
}

class CountOne : ICount { int count() { return 1; }}
class CountTwo : ICount { int count() { return 2; }}

abstract class IFooTable&lt;T&gt; where T : ICount, new()
{
  int count() { return (new T()).count(); }
}

class FooTable&lt;T&gt; : IFooTable&lt;T&gt;
{
  void AddRow(params object[] values) {
    assert(values.length = this.count());
    ...
  }
}

class OneTable : FooTable&lt;CountOne&gt; { }
class TwoTable : FooTable&lt;CountTwo&gt; { }


But honestly I would just expect the add function to take a row. This is not something where I'd use generics, instead I'd just use mutable data structures that have constraint checks. I'm way more concerned with column names matching especially when a params statement doesn't make sure they're in the right order.

class FooTable
{
  List&lt;string&gt; columns;
  List&lt;DataRow&gt; rows;

  void AddRow(DataRow row)
  {
    assert(column names for the row match the expected values);
    rows.add(row);
  }
}


Alternatively, you could mix both approaches. Using the generics to ensure the number of columns and then adding a DataRow at a time to enforce column names match up.