0

I have these functions:

public List<int> GetInts(int someParam)
public List<int> GetMoreInts(int someParam, int anotherParam)

I changed the signature of these functions so that they will get an additional optional parameter:

public List<int> GetInts(int someParam, int offset = 0)
public List<int> GetMoreInts(int someParam, int anotherParam, int offset = 0)

Now, I want to call a wrapper function, which will call these functions with the additional, optional parameter:

public List<int> Wrapper(Func<List<int>> queryFunc)
{
    var offset = 5;
    return queryFunc(offset);
}

I will call the wrapper this way:

List<int> result = Wrapper(() => GetInts(0));

How can I accomplish it? How can I add parameters to a Func, when I don't know the signature of the function that the Func points to?

In case the reason I want to do it is relevant:

I have many functions, with different signatures, that query different db tables. Some of these queries' result set is too big, so I want to use (MySQL) the Limit function:

'some mysql query' limit offset,batchsize

And then concatenate the results at the wrapper function. So I added additional parameters (offset, batchsize) to some of the functions, And I want the wrapper function to added these parameters to the function that Func points at.

EDIT: I don't understand the reason for the down vote.

I have multiple functions with different signatures which query my db.

The problem is that in some cases, the result set is too big and I get a timeout exception.

Because the result set is too big, I want to get small chunks of result sets, then concatenate them all into the complete result set.

For example: the original result set size is 500K which causes a timeout.

I want to get result sets sized at 1K, 500 times.

That's why I need to control the offset from within the Wrapper, so that at each iteration, I could send the offset, which is incremented after every iteration, as a parameter to the original function.

Alonzzo2
  • 959
  • 10
  • 24

2 Answers2

5

You just need to make a Func that takes the single int and returns the List<int>.

public List<int> Wrapper(Func<int, List<int>> queryFunc)
{
    var offset = 5;
    return queryFunc(offset);
}

Then you'd have to use it by passing in lambdas where you call your other functions with the desired params and passing in the lambdas argument as the offset.

var result1 = Wrapper(o => GetInts(someParam, o));
var result2 = Wrapper(o => GetMoreInts(someParam, anotherParam, o));

Though I'm not sure how useful that really is. If the offset is something global you might want to inject it instead of passing it to these functions by making it a field of the class that they belong to.

juharr
  • 31,741
  • 4
  • 58
  • 93
  • 2
    If you don't want a return value, try `Action` instead of `Func`. – Tân Oct 27 '16 at 11:32
  • Or specify return type of the Func as List – Andrei Oct 27 '16 at 11:33
  • @Andrei Yeah, missed that part. – juharr Oct 27 '16 at 11:34
  • @TânNguyễn Nope, I just forgot to add the return type. – juharr Oct 27 '16 at 11:38
  • Actually, your answer is very useful, since the offset will be per function. So I can do something like this: var result = Wrapper(offset => GetInts(1,offset), 5) public List Wrapper(Func> queryFunc, int offset){ return queryFunc(offset); } And now I can use a different offset each time I use the wrapper for ANY query function, regardless of its signature, which is great – Alonzzo2 Oct 27 '16 at 15:11
1

I think you wrapper should look like this:

 public List<int> Wrapper(int x, int y, Func<int,int,List<int>> queryFunc)
    {            
        return queryFunc(x, y);            
    }

This is if you want to pass the parameter from outside. Also, this is the wrapper for the public List<int> GetMoreInts(int someParam, int anotherParam, int offset = 0)

I hope I have understood your problem.

Nadeem Khoury
  • 886
  • 6
  • 18