How to pass a delegate with different number of arguments than originally designed

佐手、 提交于 2020-04-18 07:11:09

问题


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


回答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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!