Duplicate code in similar classes where I cannot add more inheritance I'm building a .NET Linq-esc query builder for my application and I'm wondering about my implementation and code structure when it comes a few classes.

Basically I'm creating a query builder for SQL, and I need for my classes to be able to using the following behavior:

query.Select(...).From(...).Join(...).Where(...);


I have created 6 Interfaces that contain one method each that donates what can be done to that class E.G the Select class would implement IFromAble which contains the method From(..). This allows the behavior above.

This is the same for all of the other classes above and a few more. Some classes, like Join will implement a few of the interfaces E.g IJoinAble, IWhereAble, IOrderAble, IGroupAble, IHavingAble.

This, as you can imagine will lead to a lot of duplicated code throughout each of my classes.

Each of the classes also implement a common base abstract class, which means I cannot use abstracts to solve the issue.

Is there another way I can implement my intended behavior without all of the duplicated code? Or is this just one of those cases I'm once again tripped up by C#'s single inheritance?

The Join Class

public class ModuleJoin : QueryModule, IJoinAble, IWhereAble, IOrderAble, IGroupAble
{
    public JoinType JoinType { get; set; }
    public QueryField JoinFrom 
    {
        get { return (QueryField)this.Fields[0]; }
        set { this.Fields[0] = value; } 
    }
    public QueryField JoinTo
    {
        get { return (QueryField)this.Fields[1]; }
        set { this.Fields[1] = value; }
    }

    public ModuleJoin(Query query, JoinType joinType, QueryField joinFrom, QueryField joinTo)
    {
        this.PerentQuery = query;
        this.Fields.Clear();
        this.Fields.Add(joinFrom);
        this.Fields.Add(joinTo);
        JoinType = joinType;
    }

    public ModuleJoin Join(JoinType joinType, QueryField joinFrom, QueryField joinTo)
    {
        ModuleJoin join = new ModuleJoin(this.PerentQuery, joinType, joinFrom, joinTo);
        this.PerentQuery.ModuleJoins.Add(join);
        return join;
    }

    public ModuleWhere Where(IFieldPart itemOne, Comparator comparator, IFieldPart itemTwo)
    {
        ModuleWhere where = new ModuleWhere(this.PerentQuery, itemOne, comparator, itemTwo);
        this.PerentQuery.ModuleWheres.Add(where);
        return where;
    }

    public ModuleGroupBy GroupBy(params IFieldPart[] fields)
    {
        ModuleGroupBy groupBy = new ModuleGroupBy(this.PerentQuery, fields);
        this.PerentQuery.ModuleGroupBy = groupBy;
        return groupBy;
    }
}


QueryModule (The interface on this just has those properties)

public abstract class QueryModule : IQueryModule
{
    public Query PerentQuery { get; set; }
    public FieldCount FieldCount { get; set; }
    public List&lt;IFieldPart&gt; Fields { get; set; }
    public IFieldPart Field
    {
        get { return Fields[0]; }
        set 
        {
            if (Fields.Count == 1)
                Fields[0] = value;
            else
                Fields.Add(value);
        }
    }

    public QueryModule()
    {
        this.Fields = new List&lt;IFieldPart&gt;();
    }
}


IJoinAble (An example of one of the interfaces)

interface IJoinAble
{
    ModuleJoin Join(JoinType joinType, QueryField joinFrom, QueryField joinTo);
}
Interesting question. The most simple and direct way to approach this problem (not necessarily the wisest) - implement Select(), From(), Join() etc. as extension methods on the interfaces ISelectable, IFromable, IJoinable, etc. The ability to write extension methods to interfaces is a powerful and fascinating language feature with many implications...