CLR之委託的揭祕(二)

 

雜談

             在開始真正的代碼以前,分析一下上週的一些工做內容,發現本身在代碼上仍是有不少小毛病須要糾正和去更改的,首先以前一直疏於文檔的整理,幾乎不多去寫文檔,第二對於接口開發過程當中缺乏必定的嚴謹性,不少問題沒有考慮清楚就已經代碼敲完了,其實應該先針對接口去寫一份接口說明文檔,一方面提高本身的文檔能力,另一方面也經過文字整理本身的思路,還有就是程序開發中不能懶,由於懶已經出了不少問題,程序畢竟是嚴謹的,你忽能它,它也必然忽能你!安全

            這是上週工做中的一些總結,接下來繼續以CLR的角度分析委託,上一節說了委託的定義,委託鏈,還有匿名委託。接下來咱們分析ide

 

泛型委託

          其實我對於泛型委託以前也是徹底只知其一;不知其二,有一次在用Linq的時候,先用了Where有用了Find,個人本意是先篩選在查找,但實際上二者基本上是一回事,都是泛型委託,固然關於泛型委託不得不說的就是 Action<T> 泛型委託, Func<T, TResult>,二者是有區別的this

            Action<T> 泛型委託:封裝一個方法,該方法只採用一個參數而且不返回值。可使用此委託以參數形式傳遞方法,而不用顯式聲明自定義的委託。該方法必須與此委託定義的方法簽名相對應。也就是說,封裝的方法必須具備一個經過值傳遞給它的參數,而且不能返回值。固然泛型委託不僅是隻能支持一個參數,它最多能夠支持四個參數。  spa

          Func<T, TResult> 委託:封裝一個具備一個參數並返回 TResult 參數指定的類型值的方法。同理,這裏的泛型委託只是接受一個參數的委託,它最多一樣支持四個參數。TResult:此委託封裝的方法的返回值類型。code

Action T

            還記得上一篇文章中咱們關於委託的定義和聲明中,是如何要求的麼?委託的安全性很是高,因此在聲明委託時,要聲明委託返回的類型和參數類型,可是在 Action<T> 上,咱們不須要如此,接下來看一下普通聲明和Action<T> 聲明的委託有什麼不一樣對象

        /*
         泛型委託和普通委託的聲明對比
         1.不須要使用delegate關鍵字
         2.Action只能使用返回值爲void的方法,若是返回值具備對象類型則報錯
         */
        delegate void DisplayMessage(string message);
        static void Main(string[] args)
        {

            DisplayMessage messageTarget;
            messageTarget = ShowWindowsMessage;
            messageTarget("Hello, World!");


            Action<string> messageTarget1;
            messageTarget1 = ShowWindowsMessage;
            messageTarget1("泛型委託");
        }
        public static void ShowWindowsMessage(string s) {
            Console.WriteLine(s);
        }
View Code

         我在註釋里加入了一行解釋:不須要使用delegate關鍵字,爲何 Action<T> 能夠直接聲明使用呢?這和其自身封裝有關,下面代碼就是其在系統中的封裝,能夠看出來,Action在元數據中就已經存在了public delegate void封裝,明確了其使用的範圍blog

  //
    // 摘要:
    //     封裝一個方法,該方法只有一個參數而且不返回值。
    //
    // 參數:
    //   obj:
    //     此委託封裝的方法的參數。
    //
    // 類型參數:
    //   T:
    //     此委託封裝的方法的參數類型。此類型參數是逆變。便可以使用指定的類型或派生程度更低的類型。有關協變和逆變的更多信息,請參見泛型中的協變和逆變。
    public delegate void Action<in T>(T obj);
View Code

Func<T, TResult>

        關於Func<T, TResult> 委託,和  Action<T> 委託的區別最大點在於Func<T, TResult>支持返回類型,剛纔咱們看了 Action<T> 之後會以爲  Action<T>  只能用於void方法,那麼若是方法返回int, Action<T> 是否是就不能用了?對的,不能用了。接口

        Func<T,TResult> 的表現形式分爲如下幾種:開發

      1。Func<T,TResult>文檔

      2。Func<T,T1,TResult>

      3。Func<T,T1,T2,TResult>

      4。Func<T,T1,T2,T3,TResult>

      5。Func<T,T1,T2,T3,T4,TResult>

      其實以上的幾種表現形式就是Func<T,TResult>的幾種重載,最多支持四個參數的重載,分別說一下各個參數的意義,TResult表示 委託所返回值 所表明的類型, T,T1,T2,T3,T4表示委託所調用的方法的參數類型,

如下是使用示例:

  /*
         使用普通委託和泛型委託一樣完成一個返回值爲string,參數爲int方法的委託調用
            */
        delegate string DisplayMessage(int message);
        static void Main(string[] args)
        {
            DisplayMessage messageTarget;
            messageTarget = Kuadi;
            Console.WriteLine(messageTarget(2));
            //Func<T,TResult> 
            Func<int,string>  messageTarget1;
            messageTarget1 = Kuadi;
            Console.WriteLine(messageTarget1(1));
        }
        public static string Kuadi(int zhong) {
            if (zhong == 1)
                return "你的快遞";
            else
                return "沒有你的貨";
        }
View Code

       能夠看的出來,泛型委託實際上比起普通委託最大好處就是能夠少些不少代碼,在之後的代碼中能夠用泛型委託完成的就不須要使用普通委託去完成,剛纔文章中提到了一個委託在linq中得使用,那麼linq中如何體現的Action<T> 泛型委託和 Func<T, TResult>泛型委託的呢

Linq中的泛型委託使用

namespace System.Linq
{
    public static class Enumerable
    {
    public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate); 
    }
}

         因爲Linq中的方法實在有點多,今天咱們只看一下Where,固然具體實現是看不到,可是咱們在這串代碼中卻看到了一個身影Func<TSource, bool>這實際上涉及了linq的內部另外一個方法的調用,這串代碼所作的事就是把條件做爲一個參數傳給predicate調用其內部方法,最終返回一個bool值。

       固然了委託用在Liqn中不僅是這麼一個地方,還有不少地方都用到了委託,感興趣的小夥伴能夠研究一下,委託在LInq中的使用

相關文章
相關標籤/搜索