2015-10-16 3 views
3

Я наклоняю delagate и лямбда выражения. Я написал несколько тестовых кодов, которые используют Count(), некоторые из них работают, но в последнее время не работают, я не знаю почему. Пожалуйста, помогите мне с объяснением. Спасибо.Делегат для предиката не работает

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; 
} 
+0

Спасибо очень много. – peter

ответ

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

Это не является действительным. isOdds возвращает bool и принимает целое число, и его необходимо как Predicate<int>. Но вы не можете отправлять его напрямую, так как они не одного типа. Вы должны использовать другую лямбду.

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

То же самое для ISEVEN

Существует и другой способ. вы можете создать новый Predicate.

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

Большое спасибо – peter

0

delegate Boolean IsOdds<T>(T x) В основном эквивалентна Predicate<T> и delegate bool IsEven(int x) эквивалентно Predicate<int> Таким образом, вы можете опустить декларацию собственных делегатов и написать что-то вроде этого:

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()); 
    } 
Смежные вопросы