// Создать список целочисленных значений.

  List list = new List();

  list.AddRange(new int[] { 20, 1, 4, 8, 9, 44 });

  // Вызвать FindAll() с применением традиционного синтаксиса делегатов.

  Predicate callback = IsEvenNumber;

  List evenNumbers = list.FindAll(callback);

  Console.WriteLine("Here are your even numbers:");

  foreach (int evenNumber in evenNumbers)

  {

    Console.Write("{0}\t", evenNumber);

  }

  Console.WriteLine();

}

// Цель для делегата Predicate<>.

static bool IsEvenNumber(int i)

{

  // Это четное число?

  return (i % 2) == 0;

}

Здесь имеется метод (IsEvenNumber()), который отвечает за проверку входного целочисленного параметра на предмет четности или нечетности с применением операции получения остатка от деления (%) языка С#. Запуск приложения приводит к выводу на консоль чисел 20, 4, 8 и 44.

Наряду с тем, что такой традиционный подход к работе с делегатами ведет себя ожидаемым образом, IsEvenNumber() вызывается только при ограниченных обстоятельствах — в частности, когда вызывается метод FindAll(), который возлагает на нас обязанность по полному определению метода. Если взамен использовать анонимный метод, то можно превратить это в локальную функцию и код станет значительно чище. Добавьте в класс Program следующий новый метод:

static void AnonymousMethodSyntax()

{

  // Создать список целочисленных значений.

  List list = new List();

  list.AddRange(new int[] { 20, 1, 4, 8, 9, 44 });

  // Теперь использовать анонимный метод.

  List evenNumbers =

    list.FindAll(delegate(int i) { return (i % 2) == 0; } );

  // Вывести четные числа

  Console.WriteLine("Here are your even numbers:");

  foreach (int evenNumber in evenNumbers)

  {

    Console.Write("{0}\t", evenNumber);

  }

  Console.WriteLine();

}

В данном случае вместо прямого создания объекта делегата Predicate и последующего написания отдельного метода есть возможность определить метод как анонимный. Несмотря на шаг в правильном направлении, вам по-прежнему придется применять ключевое слово delegate (или строго типизированный класс Predicate) и обеспечивать точное соответствие списка параметров:

List evenNumbers = list.FindAll(

  delegate(int i)

  {

    return (i % 2) == 0;

  }

);

Для еще большего упрощения вызова метода FindAll() могут использоваться лямбда-выражения. Во время применения синтаксиса лямбда-выражений вообще не приходится иметь дело с лежащим в основе объектом делегата. Взгляните на показанный далее новый метод в классе Program:

static void LambdaExpressionSyntax()

{

  // Создать список целочисленных значений.

  List list = new List();

  list.AddRange(new int[] { 20, 1, 4, 8, 9, 44 });

  // Теперь использовать лямбда-выражение С #.

  List evenNumbers = list.FindAll(i => (i % 2) == 0);

  // Вывести четные числа.

  Console.WriteLine("Here are your even numbers:");

  foreach (int evenNumber in evenNumbers)

  {

    Console.Write("{0}\t", evenNumber);

  }

  Console.WriteLine();

}

Обратите внимание на довольно странный оператор кода, передаваемый методу FindAll(), который на самом деле и представляет собой лямбда-выражение. В такой версии примера нет вообще никаких следов делегата Predicate (или ключевого слова delegate, если на то пошло). Должно указываться только лямбда-выражение:

i => (i % 2) == 0

Перейти на страницу:

Похожие книги