2010-07-16 65 views
2

我已經從Microsoft下載了VCSharpSample包,並開始閱讀匿名代理。我可以或多或少地理解代碼正在做什麼,但我不明白其背後的原因。也許如果你給了我一些例子,它會導致更簡潔的代碼和更容易的可維護性,那麼我可以圍繞它來包裹我的頭。 :)請幫我理解匿名代表?

你能幫忙嗎?

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

回答

8

匿名代理旨在幫助您通過在另一個方法中內聯定義簡單委託的行爲來使代碼更具可讀性。這意味着如果你正在處理需要委託的事情(例如事件處理程序),則可以在代碼中正確定義行爲,而不是爲其創建專用功能。

另外,它們是lambda表達式的前兆。像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; 
} 

它實現是很重要的,雖然,lambda表達式和匿名委託只是合作mpiler功能。當你的代碼被編譯時,確實實際上像上例中那樣創建了常規函數,但是它們是隱藏的,並且使用在所使用的語言中是非法的字符命名。當執行諸如閉包(如果你訪問lambda /匿名委託聲明之外的變量),還有很多邏輯繞過它們。

+0

+1:非常好.. – 2010-07-16 16:08:25

+0

+1愛你的lambda示例。打破它非常好。你認爲你可以把它分解成類似的事件嗎? – jsmith 2010-07-16 16:10:23

+0

所以它們基本上只在你創建一個只有一行代碼的方法時纔有用?爲了避免看到它每次都做什麼? – 2010-07-16 16:12:36

1

的好處是,你沒有看別的地方的代碼做一次查找/變更/計算/不管。對於只能在一個地方使用的函數(或者一個函數的其他類),添加一個函數(或者其他類)是非常煩人的,然後你必須稍後回顧一下,看看代碼是什麼以及它爲什麼是是否需要,是否仍然存在。

對於匿名代理,代碼就在使用它的代碼中。

+0

啊哈!現在我可以看到它用於這個問題中發佈的特定示例。但是,如果所討論的方法只有一行代碼,這不會有用嗎? – 2010-07-16 16:10:02

+0

可能。最適合非常小的一次性功能。如果你的匿名函數太大,它也會增加其包含函數的大小 - 並且保持函數很小(這通常是一個好主意)意味着將代碼分解成實際函數並按名稱使用它。 (如果功能很大,希望你能在其他地方使用它) – cHao 2010-07-16 16:14:51