0

I have the following issue:

  1. I have designed a framework that uses a generic delegate function (Func<...>) to calculate distance between two real number vectors

  2. The delegate has the following form:

    Func<double[], double[], double> distance;
    
  3. I have many different distance functions implemented

  4. I would rather not change the signature of distance delegate

  5. 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;
    
  6. 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

Sebastian Widz
  • 1,962
  • 4
  • 26
  • 45
  • can you not use the `Func delegate in .net 3.5` as the parameter in your RunTheMethod method. `The Func delegate allows you to specify a method that takes a number of parameters of a specific type and returns a single argument of a specific type` – MethodMan Oct 13 '14 at 21:11
  • [Passing a Method as a Parameter](http://stackoverflow.com/questions/2082615/pass-method-as-parameter-using-c-sharp) – MethodMan Oct 13 '14 at 21:12
  • Hi, thanks for your comment. I am aware of that - that is my question about, I want to preserve the signature with just two parameters (double[] vector1, double[] vector2). But I would also like to define a method with 4 parameters and pass it to the old interface. – Sebastian Widz Oct 13 '14 at 21:37

2 Answers2

2

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 !!! :)

Sebastian Widz
  • 1,962
  • 4
  • 26
  • 45
1

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;
    ...
}
David
  • 10,458
  • 1
  • 28
  • 40
  • Hi Aravol, thanks for your suggestion. I can change the interface of course, but I still believe this can be done in different way without changing the API. – Sebastian Widz Oct 13 '14 at 21:41