Can I have a variable number of generic parameters?

You can't. That is a key part of the API. You could, however, do something around the side, such as accepting a Type[] argument. You might also think up some exotic "fluent API / extension method" way of doing it, but to be honest it probably won't be worth it; but something like:

obj.Merge<FirstType>(firstData).Merge<SecondType>(secondData)
     .Merge<ThirdType>(thirdData).Execute<TDestination>(dest);

or with generic type inference:

obj.Merge(firstData).Merge(secondData).Merge(thirdData).Execute(dest);

Each merge step would simple store away the work to do, only accessed by Execute.


It depends on whether you want your objects to be able to merge objects of different types or not.

For a homogeneous merge, all you need is this:

public interface IMerger<TSource, TDestination> {
    TDestination Merge(IEnumerable<TSource> sources, TDestination destination);
}

For a heterogeneous merge, consider requiring all source types to derive from a common base type:

public interface IMerger<TSourceBase, TDestination> {
    TDestination Merge(IEnumerable<TSourceBase> sources, TDestination destination);
}

I don't see any need for a param array, just pass in the collection of objects.


The params can only be at the end or argument lists and is syntactic sugar for an array:

public interface IMerger<TSources, TDestination>
{
  TDestination Merge(TDestination destination, params TSource[] sources);
}

If you want to allow any type to be used, just use object[] instead of TSource.

Note: MS had this "problem" also when they did the Expression stuff. They came up with a bunch of delegates Action<> and Func<> with different numbers of generic arguments, but each delegate is another type in fact.