开发者

Please help me understand anonymous delegates?

I've downloaded the VCSharpSample pack from Microsoft and started reading on Anonymous Delegates. I can more or less understand what the code is doing, but I don't understand the reason behind it. Maybe if you gave me some examples where it would result in cleaner code and easier maintainability then I could wrap my head around it. :)

Can you help?

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;

      开发者_JAVA百科      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("---------------");
        }
    }
}


Anonymous delegates are designed to help you make code more readable by being able to define the behavior of a simple delegate inline in another method. This means that if you're dealing with something that requires a delegate (an event handler, for example), you can define the behavior right in the code rather than creating a dedicated function for it.

In addition, they're the precursor for lambda expressions. Things like LINQ to Objects (any of the methods that operate on IEnumerable<T>) use delegates to perform queries on objects. For example, if you have a collection of strings and you want a query that finds all of them that are five characters long, you can do that with a lambda:

List<string> strings = ...

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

Or you could do it with an anonymous delegate:

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

If you didn't have these, your code would look something like this:

var query = strings.Where(IsFiveCharacters);

...

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

It's important to realize, though, that lambdas and anonymous delegates are just compiler features. When your code is compiled, it does actually create regular functions like in the last example, but they're hidden and named using characters that are illegal in the language being used. There's a lot of logic that goes around them when doing things like closures (where you access a variable that exists outside of the lambda/anonymous delegate declaration), as well.


The benefit is that you don't have to look somewhere else for the code to do a one-time lookup/change/calculation/whatever. It's a bit annoying to have to add a function (or a whole other class for a function!) you'll only ever use in one place, and then you have to look back later and see what that bit of code was and why it's needed and whether it still is.

With an anonymous delegate, the code is right there in the code that uses it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜