關於Action 委托和匿名方法以及lambda 表達式的一些理解


  最近要因為要使用到多線程,經常要把一些方法封起來,給線程去執行,剛開始的時候,根據自己之前學的C#知識,去創建一些委托,然后把方法作為參數傳遞給其中一個方法的線程去執行,每次都要new一些委托,實在是煩,其實知道有一些簡便的方法去做的(比如使用Action和匿名方法以及lambda 表達式),但本人有點懶,本想能自己自定義 委托就自定義委托去實現唄,最后由於越來越多這樣情況出現,就干脆好好去看看Action和匿名方法以及lambda 表達式,怎么才能更方便的去實現方法的傳遞!廢話不多說,先逐一溫習一下概念,講解過程中,有錯誤歡迎指出!

Action 委托:

概念:封裝一個方法,該方法不具有參數並且不返回值。

可以使用此委托以參數形式傳遞方法,而不用顯式聲明自定義的委托。 封裝的方法必須與此委托定義的方法簽名相對應。 也就是說,封裝的方法不得具有參數,並且不得返回值,說簡淺一點就是,當你需要去定義一個不需要參數並且不需要返回值的委托時,微軟不用我們去自己去定義,可以用Action代替你定義的委托(如果你需要傳遞參數可以用Action<T>,如果你需要參數也需要返回值可以用Func<T,TResult>,大家可以自己去了解一下! ).

平常我們要使用委托的時候,需要自定義委托,然后把符合的方法賦值給委托,讓委托去執行,例如以下代碼顯式聲明了一個名為 ShowValue 的委托,並將對 Name.DisplayToWindow 實例方法的引用分配給其委托實例:

using System;
using System.Windows.Forms;

public delegate void ShowValue();

public class Name
{
   private string instanceName;

   public Name(string name)
   {
      this.instanceName = name;
   }

   public void DisplayToConsole()
   {
      Console.WriteLine(this.instanceName);
   }

   public void DisplayToWindow()
   {
      MessageBox.Show(this.instanceName);
   }
}

public class testTestDelegate
{
   public static void Main()
   {
      Name testName = new Name("Koani");
      ShowValue showMethod = testName.DisplayToWindow;
      showMethod();
   }
}

 這是平常我們自定義委托去執行一個方法,這樣雖然清晰明了,但是卻是麻煩,每次都得根據方法簽名去自定義一些委托,增加代碼系統開銷啊,寫多了也累!那

用Action看看,方便點不!

 

下面請看一個使用Action的例子,簡化了此代碼,它所用的方法是實例化 Action 委托,而不是顯式定義一個新委托並將命名方法分配給該委托

 

using System;
using System.Windows.Forms;

public class Name
{
   private string instanceName;

   public Name(string name)
   {
      this.instanceName = name;
   }

   public void DisplayToConsole()
   {
      Console.WriteLine(this.instanceName);
   }

   public void DisplayToWindow()
   {
      MessageBox.Show(this.instanceName);
   }
}

public class testTestDelegate
{
   public static void Main()
   {
      Name testName = new Name("Koani");
      Action showMethod = testName.DisplayToWindow;
      showMethod();
   }
}

 

有了action之后直接上,省得去自定義委托了,方便了許多,明白action的好處了吧!

 

 

匿名方法:

概念:匿名方法,顧名思義就是沒有名稱的方法!

在 2.0 之前的 C# 版本中,聲明委托的唯一方法是使用命名方法。 C# 2.0 引入了匿名方法,主要是您可使用匿名方法來忽略參數列表。這意味着匿名方法可轉換為具有各種簽名的委托,通過使用匿名方法,由於您不必創建單獨的方法,因此減少了實例化委托所需的編碼系統開銷!

要將代碼塊傳遞為委托參數,創建匿名方法則是唯一的方法!請看下面示例:

//示例1,用匿名方法直接傳遞給按鈕的點擊事件去執行,不用去實例一個方法了
button1.Click += delegate(System.Object o, System.EventArgs e)
                   { 
System.Windows.Forms.MessageBox.Show("Click!"); 
                  };
//示例2,直接將匿名方法賦給委托,當然你也可以用上面我說的Action去接收匿名方法,這里只是為了方便去說明
delegate void Del(int x);
Del d = delegate(int k) { /* ... */ };

有了匿名方法,是不是方便點了,要執行什么代碼,直接用匿名方法去封裝,不用去實例一個新的方法,這種用法,在多線程下使用起來更加方便,例如:

void StartThread()
{
    System.Threading.Thread t1 = new System.Threading.Thread
      (delegate()
            {
                System.Console.Write("Hello, ");
                System.Console.WriteLine("World!");
            });
    t1.Start();
}

如果創建方法所需的系統開銷是不必要的,則指定代碼塊(而不是委托)可能非常有用。 啟動新線程即是一個很好的示例。 無需為委托創建更多方法,線程類即可創建一個線程並且包含該線程執行的代碼。上示例,里面線程的參數是一個無參數的委托(類似action),所以直接傳遞無參數的匿名方法進去就行了!無需自己再去定義委托之類!

 

 

 Lambda 表達式:

看官方對lambda表達式的解析!

Lambda 表達式是一種可用於創建委托或表達式目錄樹類型的匿名函數。 通過使用 lambda 表達式,可以寫入可作為參數傳遞或作為函數調用值返回的本地函數。 Lambda 表達式對於編寫 LINQ 查詢表達式特別有用。

是不是,看着一頭霧水,不錯,我也是,官方的東西總是文縐縐的,簡單來說簡化了匿名函數的使用,讓你讓代碼更加簡潔,優雅,用運算符 " => "表示,左邊指定輸入

參數,右邊是lambda的主體!

lambda表達式:

 

1.一個參數:param=>expr

看示例:

delegate int del(int i);
static void Main(string[] args)
{
    del myDelegate = x => x * x;
    int j = myDelegate(5); //j = 25
}

這是lambda表達式的表示,注意:只有一個輸入參數時,括號才是可選的;否則括號是必需的。 括號內的兩個或更多輸入參數使用逗號加以分隔。

2.多個參數:(param-list)=>expr

//示例1
(x, y) => x == y
//示例2
(x,y,z) => SomeMethod();

lambda表達式也是可以和action結合進行使用,例如:

using System;
using System.Windows.Forms;

public class Name
{
   private string instanceName;

   public Name(string name)
   {
      this.instanceName = name;
   }

   public void DisplayToConsole()
   {
      Console.WriteLine(this.instanceName);
   }

   public void DisplayToWindow()
   {
      MessageBox.Show(this.instanceName);
   }
}

public class LambdaExpression
{
   public static void Main()
   {
      Name testName = new Name("Koani");
//此處是lambda表達式和action結合
      Action showMethod = () => testName.DisplayToWindow();
      showMethod();
   }
}

 

Lambda 的一般規則如下:

  • Lambda 包含的參數數量必須與委托類型包含的參數數量相同。

  • Lambda 中的每個輸入參數必須都能夠隱式轉換為其對應的委托參數。

  • Lambda 的返回值(如果有)必須能夠隱式轉換為委托的返回類型。

 

(有問題,大家多少交流836911886,加我請記得說:博客園)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM