Пожалуйста, помогите мне понять анонимных делегатов? - PullRequest
2 голосов
/ 16 июля 2010

Я скачал пакет VCSharpSample от Microsoft и начал читать анонимных делегатов.Я могу более или менее понять, что делает код, но я не понимаю причину этого.Может быть, если бы вы привели мне несколько примеров, в которых это привело бы к более чистому коду и более легкому обслуживанию, тогда я мог бы обернуться вокруг него.:)

Вы можете помочь?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    delegate decimal CalculateBonus(decimal sales);

    class Player
    {
        public string Name;
        public decimal Score;
        public decimal Bonus;
        public CalculateBonus calculation_algorithm;
    }

    class Program
    {        
        static decimal calculateStandardBonus(decimal sales)
        {
            return sales / 10;
        }

        static void Main(string[] args)
        {
            decimal multiplier = 2;

            CalculateBonus standard_bonus = new CalculateBonus(calculateStandardBonus);
            CalculateBonus enhanced_bonus = delegate(decimal sales) { return multiplier * sales / 10; };

            Player[] players = new Player[5];

            for (int i = 0; i < 5; i++)
            {
                players[i] = new Player();
            }

            players[0].Name = "Sergio";
            players[0].Score = 240;
            players[0].calculation_algorithm = standard_bonus;

            players[1].Name = "Sergio";
            players[1].Score = 240;
            players[1].calculation_algorithm = enhanced_bonus;

            players[2].Name = "Caro";
            players[2].Score = 89;
            players[2].calculation_algorithm = standard_bonus;

            players[3].Name = "Andy";
            players[3].Score = 38;
            players[3].calculation_algorithm = enhanced_bonus;

            players[4].Name = "Hugo";
            players[4].Score = 600;
            players[4].calculation_algorithm = enhanced_bonus;

            foreach (Player player in players)
            {
                PerformCalculationBonus(player);
            }

            foreach (Player player in players)
            {
                DisplayPersonalDetails(player);
            }

            Console.ReadLine();
        }

        public static void PerformCalculationBonus(Player player)
        {
            player.Bonus = player.calculation_algorithm(player.Score);
        }

        public static void DisplayPersonalDetails(Player player)
        {
            Console.WriteLine(player.Name);
            Console.WriteLine(player.Score);
            Console.WriteLine(player.Bonus);
            Console.WriteLine("---------------");
        }
    }
}

Ответы [ 2 ]

8 голосов
/ 16 июля 2010

Анонимные делегаты предназначены для того, чтобы помочь вам сделать код более читабельным благодаря возможности определения поведения простого делегата, встроенного в другой метод. Это означает, что если вы имеете дело с чем-то, что требует делегата (например, обработчик события), вы можете определить поведение прямо в коде, а не создавать для него специальную функцию.

Кроме того, они являются предшественниками лямбда-выражений. Такие вещи, как LINQ to Objects (любой из методов, работающих с IEnumerable<T>), используют делегаты для выполнения запросов к объектам. Например, если у вас есть коллекция строк и вы хотите запрос, который находит все из них длиной пять символов, вы можете сделать это с помощью лямбды:

List<string> strings = ...

var query = strings.Where(s => s.Length == 5);

Или вы можете сделать это с анонимным делегатом:

var query = strings.Where(delegate(string s) { return s.Length == 5; });

Если у вас их нет, ваш код будет выглядеть примерно так:

var query = strings.Where(IsFiveCharacters);

...

private bool IsFiveCharacters(string input)
{
    return input.Length == 5;
}

Важно понимать, что лямбда-выражения и анонимные делегаты - это просто функции компилятора. Когда ваш код скомпилирован, он действительно создает обычные функции, как в предыдущем примере, но они скрыты и имеют имена, которые являются недопустимыми в используемом языке. Есть много логики, которая обходит их при выполнении таких вещей, как замыкания (когда вы обращаетесь к переменной, которая существует вне лямбда / анонимного объявления делегата), а также.

1 голос
/ 16 июля 2010

Преимущество заключается в том, что вам не нужно искать код в другом месте, чтобы выполнить одноразовый поиск / изменение / расчет / что угодно. Немного раздражает необходимость добавлять функцию (или целый другой класс для функции!), Которую вы когда-либо будете использовать только в одном месте, а потом вам придется оглянуться назад и посмотреть, что это был за фрагмент кода и почему он нужен ли он и сейчас.

С анонимным делегатом код находится прямо в коде, который его использует.

...