Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic class with dynamic number of types

Tags:

c#

generics

I don't know how to phrase this question without using an example, so here we go...

I have defined a class like this:

public class Orchestration<T1, T2, T3>
{

With this constructor:

public Orchestration(Action<T1, T2, T3> action, int maxNumberOfRetries)

And a method called Run:

public bool Run(T1 one, T2 two, T3 three)

Now, if I do this:

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

then the orchestration will try to run File.Copy 5 times before it return false, meaning the job has failed (the background here is that I was trying to rescue som files from a disk that only worked now and then)

The Orchestration class is generic and I can use it to run any method that has three parameters.

My question is this: Can I define the Orchestration-class in a manner that the number of parameters does not need to be determined in advance?

My goal then would be to enable it to run any method, not only methods that takes three parameters...

like image 279
Petew Avatar asked Apr 18 '14 19:04

Petew


2 Answers

There is not a way to do this with generics in C#. This would require something similar to variadic templates in C++, but there is no equivelent in the managed world. That's why classes such as Tuple have so many different classes with the factory methods to create the various versions.

If your parameters were either non-generic (ie: object) or always string, you could use params to allow a variable number of arguments.

like image 67
Reed Copsey Avatar answered Sep 19 '22 23:09

Reed Copsey


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.

like image 44
Servy Avatar answered Sep 21 '22 23:09

Servy