How to Have a Variable Number of Generic Parameters

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.

c# method with variable number of generic parameters

I'd change your wrapper signature as follows:

async Task<TResult> RunTask<TResult>(Func<TResult> ebayAction)

And run it as

RunTask(() => SearchItems(keyword));

If you have another method with another number of arguments:

RunTask(() => SearchItems(keyword, argument2, argument3));

You can add more overloads if necessary, like:

// some action which does not return result
static async Task RunTask(Action ebayAction)
// some function which is already asynchronous so you don't need
// to wrap it into Task.Run
static async Task<TResult> RunTask<TResult>(Func<Task<TResult>> ebayAction)

Typescript generic for function with a variable number of parameters

You may want to have a look at tuple rest parameters, which are used to emulate functions with a variable number of parameters. A possible solution:

// We pass in a tuple of classes. This tuple is generically typed (type parameter T)
// { new(...arg: any): any } is constructor function type for a class
function findObjects<T extends { new(...arg: any): any }[]>(...cls: T): Partial<T> {
// search for objects that are instances of these classes; return filtered classes
}

class Component { c = "c" }
class A extends Component { a = "a" }
class B extends Component { b = "b" }

const res = findObjects(A, B) // [(typeof A | undefined)?, (typeof B | undefined)?]

For the return type I used Partial<T>, which is a mapped tuple with optional elements of the passed in classes. It contains undefined at an index, if the corresponding class item is filtered out by your findObjects implementation (adjust the return type like you need it).

Playground

Passing a variable number of generic type parameters

If, as you say, you want to be able to pass completely unrelated lists, maybe you should accept the base IList interface:

public void Export(string FileName, params IList[] Data)

All List<T> objects implement IList, as well as the generic IList<T>, so you can enforce that.

Actually, depending on what you need to do with these lists in the Exporter, perhaps enforcing IEnumerable is enough for you, if all you need is forward-only read-once functionality.

Best way to decide is to determine what the shared functionality you need for all parameters, and define your method signature to enforce that functionality.

UPDATE

Based on your comment, it seems what you want is possible in C# 4.0 using covariant/contravariant generics, meaning that a generic ISomething<out object> could receive an ISomething<string>. The problem is that IList<T> doesn't define a covariant generic parameter, so passing IList<string> for IList<object> doesn't work.

However, IList<T> inherits IEnumerable<out T>, which DOES define a covariant parameter. So if your Export method receives a params IEnumerable<object>[] data parameter, you SHOULD be able to pass it any IList<T> you want.

Generic class with dynamic number of types

Just have it accept an Action and close over whatever parameters you would have for your actual method:

public Orchestration(Action action, int maxNumberOfRetries)

var orchestration = new Orchestration(
() => File.Copy("c:\filename.txt", "d:\filename.txt", true), 5);

It means knowing the parameter values on construction, rather than when calling Run, but in this context that doesn't seem like it should be a problem you can't resolve.

Create a class with a variable number of generic type

No, types in Java have a fixed number of type parameters.

The closest you could get is to have a (finite) number of related classes:

class Tuple1<A> { ... }

class Tuple2<A, B> { ... }

class Tuple3<A, B, C> { ... }

And then provide a common class with factory methods:

class Tuples {
static <A> Tuple1<A> of(A a) { ... }
static <A, B> Tuple2<A,B> of(A a, B b) { ... }
static <A, B, C> Tuple1<A,B,C> of(A a, B b, C c) { ... }
}

In Java, can I specify any amount of generic type parameters?

Is anything like this available? I have read about variadic templates
in C++, but cannot find anything similar in Java. Is any such thing
available?

No, this feature is not available in Java.



Related Topics



Leave a reply



Submit