2017-10-04 72 views
3

我對理解使用委託的概念有一些懷疑,下面是我有的委託示例。使用或不使用委託有什麼區別

本示例使用Photo過濾軟件作爲實例,它將爲照片添加過濾器,並且使用委託將增加將來添加新過濾器的靈活性。

class Photo 
    { 
     private string path; 

     public Photo(string path) 
     { 
      this.path = path; 
      Console.WriteLine("{0} imported", path); 
     } 

     public void Save() 
     { 
      Console.WriteLine("{0} photo saved", this.path); 
     } 
    } 

PhotoFilter.cs:

class PhotoFilter 
{ 
    public void AddBrigtness(Photo photo) 
    { 
     Console.WriteLine("Added Brightness"); 
    } 

    public void AddFilter(Photo photo) 
    { 
     Console.WriteLine("Added Filter"); 
    } 

    public void AddShadow(Photo photo) 
    { 
     Console.WriteLine("Added Shadow"); 
    } 
} 

PhotoProcesser.cs:

class PhotoProcesser 
{ 
    public void Process(string path) 
    { 
     var photo = new Photo(path); 
     var filter = new PhotoFilter(); 

     filter.AddBrigtness(photo); 
     filter.AddFilter(photo); 
     filter.AddShadow(photo); 

     photo.Save(); 
    } 
} 

使用委派

Photo.cs之前的Program.cs:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var process = new PhotoProcesser(); 
     process.Process("123.jpg"); 
    } 
} 

使用委派

*** Photo.csPhotoFilter.cs後都保持不變

PhotoProcesser.cs:

delegate void PhotoMethodHandler(Photo p); // Delegate 

    class PhotoProcesser 
    { 
     public void Process(string path,PhotoMethodHandler methodHandler) 
     { 
      var photo = new Photo(path); 

      methodHandler(photo); 

      photo.Save(); 
     } 
    } 

Program.cs:

class Program 
    { 
     static void Main(string[] args) 
     { 
      var filter = new PhotoFilter(); 

      PhotoMethodHandler p = filter.AddBrigtness; 
      p += filter.AddFilter; 
      p += RemoveRedEyeFilter; // To simulate the flexibility of using Delegate 

      var process = new PhotoProcesser(); 
      process.Process("123.jpg",p); 
     } 

     static void RemoveRedEyeFilter(Photo photo) // Newly added filter 
     { 
      Console.WriteLine("Added RemoveRedEye"); 
     } 
    } 

輸出:

enter image description here

在這一點上,我可以理解使用委託作爲函數指針, 的靈活性,但如果我們以另一種方式思考,我們也可以得到同樣的結果,如果我們不使用PhotoProcesser.cs和改變的Program.cs如下:

的Program.cs:

class Program 
    {  
     static void Main(string[] args) 
     { 
      var photo = new Photo("p1.jpg"); 
      var filter = new PhotoFilter(); 

      filter.AddBrigtness(photo); 
      filter.AddFilter(photo); 
      RemoveRedEyeFilter(photo); 

      photo.Save(); 

     } 

     static void RemoveRedEyeFilter(Photo photo) // Newly added filter 
     { 
      Console.WriteLine("Added RemoveRedEye"); 
     } 
    } 

輸出:

enter image description here

它會得到相同的結果,相同的靈活性(要在這種情況下,添加一個新的過濾器)的使用委託。

根據上面的例子,任何人都可以給我一些方向,瞭解什麼是使用委託的好處/不同?謝謝!

+0

這可能幫助你:https://stackoverflow.com/questions/1334736/events-with-and-without-delegates-in-asp-net – Sinil

+0

事件處理程序是代表的孩子,所以情況是不同的。根據示例,我很困惑何時以及爲什麼要使用Delegate? – Jason

+0

就可重用性而言,如果我們需要多次處理相同的操作,那麼使用委託可以減少一些代碼。我對嗎? – Jason

回答

3

委託(包括lambda或任何指向函數的指針)背後的想法是能夠將靜態行爲(由代碼定義)轉換爲動態(由數據定義)。

比如我可以這樣做:

Photo p = new Photo(); 
p = ApplyX(p); 
p = ApplyY(p); 
... 

但隨着委託我可以做

List<Func<Photo,Photo>> filters = Whatever(); 
Photo p = new Photo(); 
foreach(var filter in filters) 
{ 
    p = filter(p); 
} 

這將讓你改變的過濾器在運行時列表(在過濾器插入和移除委託列表)。

您可以檢查此進一步閱讀:Open Closed Principle

相關問題