2

Microsoft から VCSharpSample パックをダウンロードし、Anonymous Delegates を読み始めました。コードが何をしているのかは大体理解できますが、その背後にある理由はわかりません。コードがよりクリーンになり、保守が容易になる例をいくつか挙げていただければ、頭を悩ませることができるかもしれません。:)

手伝ってくれますか?

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("---------------");
        }
    }
}
4

2 に答える 2

8

匿名デリゲートは、単純なデリゲートの動作を別のメソッドでインラインで定義できるようにすることで、コードを読みやすくするために設計されています。これは、デリゲートを必要とするもの (イベント ハンドラーなど) を扱っている場合、専用の関数を作成するのではなく、コード内で動作を定義できることを意味します。

さらに、それらはラムダ式の前身です。LINQ to Objects ( で動作する任意のメソッドIEnumerable<T>) などは、デリゲートを使用してオブジェクトに対してクエリを実行します。たとえば、文字列のコレクションがあり、5 文字の長さのすべてを検索するクエリが必要な場合は、ラムダを使用してそれを行うことができます。

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

ただし、ラムダと匿名デリゲートは単なるコンパイラ機能であることを認識することが重要です。コードがコンパイルされると、実際に最後の例のように通常の関数が作成されますが、使用されている言語では無効な文字を使用して非表示になり、名前が付けられます。クロージャー (ラムダ/匿名デリゲート宣言の外部に存在する変数にアクセスする場合) などを行う場合にも、それらを回避する多くのロジックがあります。

于 2010-07-16T16:05:43.877 に答える
1

利点は、コードが1回限りのルックアップ/変更/計算などを行うために、他の場所を探す必要がないことです。1つの場所でしか使用しない関数(または関数の他のクラス全体)を追加する必要があるのは少し面倒です。その後、後で振り返って、そのコードのビットとその理由を確認する必要があります。必要であり、それがまだあるかどうか。

匿名のデリゲートを使用すると、コードはそれを使用するコードのすぐそこにあります。

于 2010-07-16T16:04:02.523 に答える