peter
peter

Reputation: 1049

delegate for predicate not working

I am leaning the delagate and lambda expression. I wrote some test code, that use Count(), some of calls work, but last not working, I don't know why. Please help me with explanation. thank you.

public static int Count<T>(T[] arr, Predicate<T> condition)
{
    int counter = 0;
    for (int i = 0; i < arr.Length; i++)
        if (condition(arr[i]))
            counter++;
    return counter;
}

delegate Boolean IsOdds<T>(T x);
delegate bool IsEven(int x);

private void button1_Click(object sender, EventArgs e)
{
    IsOdds<int> isOdds = i => i % 2 == 1;//must be <int>, not <T>
    IsEven isEven = i => i % 2 == 0;            

    Action<int> a = x => this.Text = (x*3).ToString();
    a(3);

    Predicate<int> f = delegate(int x) { return x % 2 == 1; };
    Predicate<int> ff = x => x % 2 == 1;

    MessageBox.Show("lambada " + Count<int>(new int[] { 1, 2, 3, 4, 5 }, x => x % 2 == 1).ToString());
    MessageBox.Show("f " + Count<int>(new int[] { 1, 2, 3, 4, 5 }, f).ToString());
    MessageBox.Show("ff " + Count<int>(new int[] { 1, 2, 3, 4, 5 }, ff).ToString());
    MessageBox.Show("delegate " + Count<int>(new int[] { 1, 2, 3, 4, 5 }, delegate(int x) { return x % 2 == 1; }).ToString());
    MessageBox.Show(Count<int>(new int[] { 1, 2, 3, 4, 5 }, isOdds(int x)).ToString());  //this is wrong
    MessageBox.Show(Count<int>(new int[] { 1, 2, 3, 4, 5 }, isEven(int x)).ToString());  //this is wrong
    return;
}

Upvotes: 3

Views: 89

Answers (2)

Aleksey L.
Aleksey L.

Reputation: 37996

Basically delegate Boolean IsOdds<T>(T x) is equivalent to Predicate<T> and delegate bool IsEven(int x) is equivalent to Predicate<int> So you can omit declaration of your own delegates and write something like this:

private void button1_Click(object sender, EventArgs e)
    {
        Predicate<int> isOdds = i => i % 2 == 1;
        Predicate<int> isEven = i => i % 2 == 0;

        Action<int> a = x => this.Text = (x * 3).ToString();
        a(3);

        Predicate<int> f = delegate (int x) { return x % 2 == 1; };
        Predicate<int> ff = x => x % 2 == 1;

        MessageBox.Show("lambada " + Count<int>(new int[] { 1, 2, 3, 4, 5 }, x => x % 2 == 1).ToString());
        MessageBox.Show("f " + Count<int>(new int[] { 1, 2, 3, 4, 5 }, f).ToString());
        MessageBox.Show("ff " + Count<int>(new int[] { 1, 2, 3, 4, 5 }, ff).ToString());
        MessageBox.Show("delegate " + Count<int>(new int[] { 1, 2, 3, 4, 5 }, delegate (int x) { return x % 2 == 1; }).ToString());
        MessageBox.Show(Count<int>(new int[] { 1, 2, 3, 4, 5 }, isOdds).ToString());
        MessageBox.Show(Count<int>(new int[] { 1, 2, 3, 4, 5 }, isEven).ToString());
    }

Upvotes: 0

M.kazem Akhgary
M.kazem Akhgary

Reputation: 19179

Count<int>(new int[] { 1, 2, 3, 4, 5 }, isOdds(int x));

This is not valid. isOdds returns bool and takes integer and its must like Predicate<int>. But you cant send it directly since they are not same type. You have to use another lambda.

Count<int>(new int[] { 1, 2, 3, 4, 5 }, x => isOdds(x)); // x => isOdds(x) is now type of Predicate<int>

The same thing for isEven

There is also another way. you can create new Predicate.

Count<int>(new int[] { 1, 2, 3, 4, 5 }, new Predicate<int>(isOdds)); 

Upvotes: 3

Related Questions