Adam Wróbel
Adam Wróbel

Reputation: 453

Using Func<T> delegate in C#

Maybe my question will be too general, but I'll try to summarize everything as soon as possible.

For several days I have been teaching about delegates (Func to be exact), but I cannot understand a few things:

I. Case one:

I have method Task.Run() which can take as a parameter Func<TResult>. Why, as a delegate, using a lambda expression, I can pass a method that also has parameters - in my opinion, if a method has parameters, it is not compatible with the Func type:

static void Main(string[] args)
{
 // It's work and is ok
 Task taskOne = Task.Run(calculateOne);

 // It's work but why can i pass calculateTwo(2) as Func<TResult> ?If the parameter type is 
 // <TResult>, should the method not have any input parameters?
 Task taskTwo = Task.Run(()=> calculateTwo(2));
}

public static int calculateOne()
{
 return 1 + 9;
}

public static int calculateTwo(int t)
{
 return 1 + 9;
}

II. Case two:

In first question I can pass method with parameter as delegate when method parameter is Func<Tresult>. My second question is totally the opposite. Why, as a Func <bool, int, int> delegate, can I pass a method that takes no parameters? And why i can't pass lambda with parameters?

// Why this is ok, when BubleSort parameter type is Func<int,int,bool>?
// Shouldn't I put method parameters?
BubbleSort(GreatherThan);

// ERROR: Func <bool, int, int> means int and int are parameters, yet I can't pass 
// parameters like this
BubbleSort(()=>GreatherThan(1,2));

public static void BubbleSort(Func<int,int,bool> compare)
{}

public static bool GreatherThan(int first, int second)
{
 return first > second;
}

Upvotes: 0

Views: 999

Answers (2)

Func does not accept any parameters, so you can write lambda like this () => calculateTwo(1) and it fits Func signature

To do the same with Func<int, int, bool> you need to write like this (first, second) => GreatherThan(1,2)

But this is an incorrect useage of the Func. It designed to pass method reference for any other code, which can call it like that

public static void BubbleSort(Func<int,int,bool> compare)
{
  compare(1,2); // or something else
}

Sorry for my language :)

Upvotes: 1

Sweeper
Sweeper

Reputation: 270780

In both cases, the lambda expressions that you have written:

()=>GreatherThan(1,2)
()=> calculateTwo(2)

represent functions with no parameters, as indicated by the empty brackets (). It does not matter what you do inside the lambda expression. () => calculateTwo(2) represents a function with no parameters, that calls calculateTwo(2) as the only thing it does. Imagine these:

int AnonymousFunction1() {
    return calculateTwo(2);
}
bool AnonymousFunction2() {
    return GreaterThan(1, 2);
}

Think of as these as what you are actually passing to Task.Run by writing those lambda expressions. These functions are clearly compatible with Func<int> and Func<bool>, and not compatible with Func<int, int, bool>.

Upvotes: 2

Related Questions