Reputation: 150
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...
Upvotes: 6
Views: 2667
Reputation: 1332
No, you cannot do that.
Take a look at Tuple
s, Action
s and Func
s in the .NET API... they have to create a version of each of those generic classes that takes 1 type arguments, one that takes 2 type arguments, etc. etc.
If you want something cool, try this:
static class Extensions {
public static TimesDo( this int x, Action action) {
for (int i = 0; i < x; i++) action.Invoke();
}
}
Then:
int x = 4; x.TimesDo(() => { File.Copy( .... ) } );
or
(5).TimesDo(() => { File.Copy( .... ) });
Upvotes: 0
Reputation: 203802
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.
Upvotes: 7
Reputation: 564333
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.
Upvotes: 10