问题
I have the following issue:
I have designed a framework that uses a generic delegate function (Func<...>) to calculate distance between two real number vectors
The delegate has the following form:
Func<double[], double[], double> distance;
I have many different distance functions implemented
I would rather not change the signature of distance delegate
I need to create a new function that besides two double vectors needs some additional parameters i.e.
Func<double[], double[], double, double, double> newDistance;
This does not have to be the delegate. What I want is to define a method with additional parameters and pass it to the old interface.
can this and how, be achieved without a serious redesign and without changing the signature of distance delegate?
Regards, Sebastian
回答1:
OK I think I have found a way:
I can create a method that takes this two additional parameters and returns a Func delegate. Something like this
public static Func<double[], double[], double> NewDistanceMethodWithParams(double alpha, double beta)
{
Func<double[], double[], double> dist = (vec1, vec2) =>
{
//do some calculations on vec1 and vec2 with alpha, beta params
};
return dist;
}
First tests shows that it works !!! :)
回答2:
You could always add an object
at the end for "extra data" but as written, you cannot add extra parameters to delegates. This would disrupt the ability for your framework to call them from its end.
That being said, however, you CAN make certain lambda calls which only take the specified arguments, but then call into a method with more arguments.
double extra1 = //...
double extra2 = //...
newDistance = (firstAr, secondAr) =>
newDistanceAsMethod(firstAr, secondAr, extra1, extra2);
Also note there is a delegate
type for when you don't know the arguments at compile time, but using that can get very very tricky if you want a variable number of arguments.
My advice is to consider, despite mentioned misgivings, changing parameters on the original delegate. If you're concerned about further extensibility, make the parameters into an interface or class, and pull them out as obj.First
and such - inheritance allows you to add properties to class objects and overload methods much more easily than delegates do. Thusly distance
becomes
Func<DistanceArgs, double> distance;
...
public class DistanceArgs
{
public double[] First;
public double[] Second;
}
public class NewDistanceArgs : DistanceArgs
{
public double Extra1;
public double Extra2;
...
}
来源:https://stackoverflow.com/questions/26348890/how-to-pass-a-delegate-with-different-number-of-arguments-than-originally-design