Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I have a variable number of generic parameters?

In my project I have the following three interfaces, which are implemented by classes that manage merging of a variety of business objects that have different structures.

public interface IMerger<TSource, TDestination> {     TDestination Merge(TSource source, TDestination destination); }  public interface ITwoWayMerger<TSource1, TSource2, TDestination> {     TDestination Merge(TSource1 source1, TSource2 source2, TDestination destination); }  public interface IThreeWayMerger<TSource1, TSource2, TSource3, TDestination> {     TDestination Merge(TSource1 source1, TSource2 source2, TSource3 source3, TDestination destination); } 

This works well, but I would rather have one IMerger interface which specifies a variable number of TSource parameters, something like this (example below uses params; I know this is not valid C#):

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

It there any way to achieve this, or something functionally equivalent?

like image 799
Richard Ev Avatar asked Oct 23 '09 11:10

Richard Ev


People also ask

Can a generic class have multiple parameters?

A Generic class can have muliple type parameters.

Can a generic class have multiple generic parameters Java?

You can also use more than one type parameter in generics in Java, you just need to pass specify another type parameter in the angle brackets separated by comma.

Which keyword can be used to accept varying number of parameters?

By using the params keyword, you can specify a method parameter that takes a variable number of arguments.

What is a generic type parameter?

Generic Methods A type parameter, also known as a type variable, is an identifier that specifies a generic type name. The type parameters can be used to declare the return type and act as placeholders for the types of the arguments passed to the generic method, which are known as actual type arguments.


2 Answers

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.

like image 64
Marc Gravell Avatar answered Sep 18 '22 17:09

Marc Gravell


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.

like image 29
Christian Hayter Avatar answered Sep 18 '22 17:09

Christian Hayter