0

this might be a bit confusing so I'll try to explain my situation.

I have a function that receives another function as parameter but the latter can have different parameters.

I tried something like this:

public static async Task<IEnumerable<T>> MyFunction<T>(
    Func<int, int, params DateTime[], SomeEntity> mySmallerFunction)
{
    ...something here;
}

I want to use "params" because I have to use MyFunction in 2 different cases:

SomeEntity mySmallerFunction(int, int, DateTime)

SomeEntity mySmallerFunction(int, int, DateTime, DateTime)

The way it is, Visual Studio is accusing the errors "Type expected" and "Syntax error, 'char' expected". I don't know what I'm doing wrong or if what I'm tring to do is even possible. Can anyone help me with a solution to my problem?

  • Reopened. OP doesn't actually *want* to pass a `params` delegate (as in the [proposed duplicate](https://stackoverflow.com/questions/4059624/can-i-use-params-in-action-or-func-delegates)). Instead, he thought that params was the solution to his underlying problem (which it wasn't). – Heinzi Mar 31 '21 at 15:07
  • @Heinzi Reopening an exact dupli8cate of the question asked because you wish they would have asked a different question is not appropriate. They asked the exact question asked in the duplicate. If you think they shouldn't have asked that, that's a comment, and doesn't make the question any less of a duplicate. – Servy Mar 31 '21 at 15:19
  • @Servy: That's only true if you reduce the question to its title. If you read the question text, it's a completely different question. (And I say that as someone who usually uses his dupe hammer quite liberally and who agrees with your general sentiment.) – Heinzi Mar 31 '21 at 15:22
  • @Heinzi They do not in fact only ask how to use params in a func in the title. They do in fact also ask to do that in the question body. But of course, if you think the OP is actually asking how to create two overloads of a function to cover two different cases, then that's not actually a novel question that's never been asked before and needs a new answer. if you actually think that's what the question is asking, you can provide a duplicate with that answer. – Servy Mar 31 '21 at 15:27
  • @Servy: In my reading, the OP asks: "I have two methods with slightly different signatures which I want to pass as a parameter to the same library function. How do I do that? NB: Here's what I tried so far (using params)." This sounds like a perfectly valid question to me. Sure, it might have been asked before, but the quick search I did before answering did not find an obvious, well-fitting dupe target. – Heinzi Mar 31 '21 at 15:38
  • But they didn't ask that question. You may have wished they asked that question, but that's not the question that they asked. And saying the question is a duplicate but you just prefer to answer the question even though you think it's a duplicate isn't exactly a great look. – Servy Mar 31 '21 at 16:54
  • @Servy: Uh, yes, he *did* ask that question (see 2nd paragraph). And since my answer solved OP's problem, it seems that my interpretation was more accurate than yours. That's ok, we are all ESL speakers, and communication is hard. I guess we'll just have to agree to disagree on this one. – Heinzi Mar 31 '21 at 18:24
  • @Heinzi That you had the actual answer deleted so the OP couldn't even see it, and all they were only able to see what what you posted, you can't really argue in good faith that they felt that was the best solution. But no, their second paragraph doesn't say what you claimed at all. They gave two examples of how to call it, which isn't what you said at all. You agree to disagree on matters of opinion that have no verifiably correct or incorrect answers. Making false statements and then just saying, "I agree to disagree" makes no sense. – Servy Mar 31 '21 at 19:16
  • @Servy: Well, if we can't agree to disagree, your arguments don't convince me, and mine apparently don't convince you, how do we proceed? (Fwiw, I didn't delete anything. The link to your proposed dupe is still in the first comment to this Q.) – Heinzi Apr 01 '21 at 05:35

1 Answers1

0

As JonasH explained in his answer, the compiler won't support this. Let me suggest an alternative solution instead. Let's keep MyFunction as it is (but without the params):

public static async Task<IEnumerable<T>> MyFunction<T>(
    Func<int, int, DateTime[], SomeEntity> mySmallerFunction)
{
    ...something here;
}

Now when calling MyFunction, you can create a lambda expression which has the desired syntax and convert the array into parameters:

// Calling it with mySmallerFunction(int, int, DateTime)
MyFunction((i1, i2, dts) => mySmallerFunction(i1, i2, dts[0]));

// Calling it with mySmallerFunction(int, int, DateTime, DateTime)
MyFunction((i1, i2, dts) => mySmallerFunction(i1, i2, dts[0], dts[1]));

Obviously, this assumes that your business logic ensures that MyFunction is smart enough to know whether it needs to pass a one-element or two-element array.


Alternatively, you could declare MyFunction to always pass two DateTimes and ignore the second value when appropriate:

public static async Task<IEnumerable<T>> MyFunction<T>(
    Func<int, int, DateTime, DateTime, SomeEntity> mySmallerFunction)
{
    ...something here;
}

// Calling it with mySmallerFunction(int, int, DateTime)
MyFunction((i1, i2, dt1, dt2) => mySmallerFunction(i1, i2, dt1));

// Calling it with mySmallerFunction(int, int, DateTime, DateTime)
MyFunction(mySmallerFunction);

Obviously, you could also move that conversion logic into a second MyFunction overload instead:

public static async Task<IEnumerable<T>> MyFunction<T>(
    Func<int, int, DateTime, SomeEntity> mySmallerFunction)
{
    return MyFunction<T>((i1, i2, dt1, dt2) => mySmallerFunction(i1, i2, dt1));
}

public static async Task<IEnumerable<T>> MyFunction<T>(
    Func<int, int, DateTime, DateTime, SomeEntity> mySmallerFunction)
{
    ...something here;
}
Heinzi
  • 167,459
  • 57
  • 363
  • 519