我从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("---------------");
}
}
}
答案 0 :(得分:8)
匿名委托旨在通过在另一个方法中内联定义简单委托的行为来帮助您使代码更具可读性。这意味着如果您正在处理需要委托(例如事件处理程序)的事情,您可以在代码中定义行为,而不是为其创建专用函数。
此外,它们是lambda表达式的前身。 LINQ to Objects(在IEnumerable<T>
上运行的任何方法)之类的东西使用委托来对对象执行查询。例如,如果您有一个字符串集合,并且您希望查询找到长度为五个字符的所有字符串,则可以使用lambda执行此操作:
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;
}
然而,重要的是要认识到lambdas和匿名委托只是编译器功能。编译代码时, 实际上会创建常规函数,就像上一个示例中一样,但它们是隐藏的,并使用在所用语言中非法的字符命名。在执行诸如闭包之类的事情时(在那里你访问一个存在于lambda / anonymous委托声明之外的变量),有很多逻辑绕过它们。
答案 1 :(得分:1)
好处是您不必在其他地方查找代码以进行一次性查找/更改/计算/其他任何操作。你必须在一个地方添加一个函数(或一个函数的整个其他类!)有点烦人,然后你必须回顾一下后面看看那些代码是什么以及为什么它是需要以及它是否仍然存在。
使用匿名委托,代码就在使用它的代码中。