1. 程式人生 > 實用技巧 >delegate、Lambda表示式、Func委託和Expression(TDelegate)表示式目錄樹

delegate、Lambda表示式、Func委託和Expression(TDelegate)表示式目錄樹

1.delegate

MSDN:一種安全地封裝方法的型別,它與 C 和 C++ 中的函式指標類似。與 C 中的函式指標不同,委託是面向物件的、型別安全的和保險的。委託的型別由委託的名稱定義。

 
    class Program
    {
        const int num = 100;
        delegate bool delCompare(int a);
       static void Main(string[] args)
        {
            delCompare hander = DelegateMethod;
            hander(1);
        }

       public
static bool DelegateMethod(int a) { return a > num; } }


用IL Disassemble檢視


匿名委託:

匿名委託即使用了匿名方法的委託,IL層中的程式碼中會為匿名函式生一個靜態的函式,本次的程式碼中的函式名是:CS$<>9__CachedAnonymousMethodDelegate1

    class Program
    {
        const int num = 100;
        delegate bool delCompare(int
a); static void Main(string[] args) { delCompare del = delegate(int a) { return a > num; }; } }
用IL Disassemble檢視

2.Lambda表示式

使用Lambda表示式與上一個Demo中使用匿名函式生成的IL程式碼是完全一樣的

    class Program
    {
        const int num = 100;
        delegate bool delCompare(int
a); static void Main(string[] args) { delCompare del = a => a > num; } }


3.Func<T1..TResult>

使用Func<T1…TResult>中的Demo中,在IL層代中有所不同。程式碼中沒有用到delegate,相當於在Main方法中直接呼叫了一個靜態方法。理論上Func<T1…TResult>比delegate在時間和空間的效率都要高

    class Program
    {
        const int num = 100;
        //delegate bool delCompare(int a);
       static void Main(string[] args)
        {
            Func<int, bool> del = a => a > num;
        }
    }


4.Expression(TDelegate)

表示式目錄樹以資料形式表示語言級別程式碼。資料儲存在樹形結構中。表示式目錄樹中的每個節點都表示一個表示式。以下Demo中IL層的程式碼中並未生成任何靜態函式。

    class Program
    {
        const int num = 100;
        //delegate bool delCompare(int a);
       static void Main(string[] args)
        {
            Expression<Func<int, bool>> exp = a => a > num; //生在表示式
            Func<int,bool> fun = exp.Compile(); //編輯表示式
            fun(1); //執行表示式
        }
    }

檢視Main函式,在IL層程式碼中會對Expression動太編譯生成例項!0,再通過Invoke(!0)呼叫方法

IL_0045: callvirt instance !0 class [System.Core]System.Linq.Expressions.Expression`1<class [mscorlib]System.Func`2<int32,bool>>::Compile()
IL_004a: stloc.1
IL_004b: ldloc.1
IL_004c: ldc.i4.1
IL_004d: callvirt instance !1 class [mscorlib]System.Func`2<int32,bool>::Invoke(!0)
IL_0052: pop
IL_0053: ret

總結:

匿名delegate和Lambda表示式本質是一樣的,Func<T1..TResult>委託與delegate不同,它沒有委託的異常呼叫等特性,在IL層生成的程式碼不同,執行方式不同。Expression(TDelegate)則是語言級別的,用於動太生成表示式,理論上Expression(TDelegate)效率最差。但在Linq表示式中必須用到。

*************轉摘:https://www.cnblogs.com/xuf22/archive/2011/09/21/2184351.html