系統自帶的泛型委託Action<>,Func<>, Predicate<>.

自定義Delegate時,我們常常發現Delegate必須全局可見,才能在需要的地方進行使用,而對於私有的delegate對象,在本類中進行使用,這似乎是不方便的。下邊我們來看傳統的Delegate的寫法:

public delegate void MyDelegate(string name);
public class MyBlogBase
{
private MyDelegate mydelegate;
}

必須保證MyDelegate放在類的外邊,才能在其他地方可見,並使用。Action,Func的出現改變了這一局面,這兩個其實說白了就是系統定義好的Delegate,他有很多重載的方法,便於各種應用情況下的調用。他在系統的System命名空間下,因此全局可見。下文就說明Action,Action有多個重載,下文已Action<T>爲例進行說明

Action<T>:封裝一個方法,該方法只有一個參數並且不返回值。其中T是可接收的任何類型。使用代碼如下:

public class MyBlogBase
    {    
        public string myName;
        Action<string> myAction; 

        public MyBlogBase()
        {
          //myAction = delegate(string curName) { myName = curName; };
          //myAction = new Action<string>(SetAction);
            myAction = curname => { myName = curname; };
        }

        private void SetAction(string name)
        {
            myName = name;
        }
    }

在上例中,給出了3種使用Action的方法,方法一:採用匿名委託,方法二:指定一個實際的方法。方法三:使用Lamda表達式。以上3中用法均可運行。

在實際應用中要比原始的定義Delegate方便,靈活。那麼Func呢?

Func<T in,T Tresult>:封裝一個具有一個參數並返回 TResult 參數指定的類型值的方法。其實個人感覺,Func和Action的區別很明顯,也很直接。二者都是委託,但Func能返回函數執行結果,而Action返回類型是Void,這個區別很明顯,在具體的項目中,也很容易確定該使用那個。下文就說明具體Func的代碼調用:

public string myName;
        Func<string, string> myFunc;     
        public MyBlogBase()
        {   
            //myFunc = delegate(string curName) { return curName.ToUpper(); };         
            //myFunc = new Func<string, string>(SetFunc);
            myFunc = name => { return name.ToUpper(); };               
        }      
        private string SetFunc(string name)
        {
            return name.ToUpper();
        }       
        public void StartFun(string curName)
        {
            myName = myFunc(curName)
        }

如上3種寫法,都是合適的Func定義,大家可以選擇適合自己的編程模式,其實匿名方法,有個優點,就是可以直接使用當前函數出現的變量,代碼更簡潔,但可能有些人覺得不易讀。

Predicate<T>:也是一種委託,表示定義一組條件並確定指定對象是否符合這些條件的方法.此方法常在集合的查找中被用到,如:數組,正則拼配的結果集中被用到。使用此方法快捷方便,使用代碼如下:

Predicate<int[]> myPredicate;
       int[] myNum = new int[8] { 12, 33, 89, 21, 15, 29, 40, 52 };
       public int[] myResult;
       public MyBlogBase()
        {    
            myPredicate = delegate(int curNum) { if(curNum % 2 == 0) return true; else return false; };
            //myPredicate = n => n % 2 == 0;
        }

        public void StartPredicate()
        {
            myResult = Array.FindAll(myNum, myPredicate);
        }

上例中說明了Predicate的使用,FindAll方法中,參數2即是一個Predicate,在具體的執行中,每一個數組的元素都會執行指定的方法,如果滿足要求返回true,並會被存放在結果集中,不符合的則被剔除,最終返回的集合,即是結果判斷後想要的集合,此方法應用場景感覺像迭代中的yield。

爲了更好的驗證運行效果,添加Test項目及進行測試,把代碼粘帖出來分享一下:

[TestMethod]
        public void TestAction()
        {
            MyBlogBase blogObj = new MyBlogBase();
            blogObj.StartAction("ywg369");
            Assert.AreEqual("ywg369", blogObj.myName);
        }

        [TestMethod]

        public void TestFunc()
        {
            MyBlogBase blogObj = new MyBlogBase();
            blogObj.StartFun("ywg369");
            Assert.AreEqual("YWG369", blogObj.myName);
        }
        [TestMethod]
         public void TestPredicate()
        {
          MyBlogBase blogObj = new MyBlogBase();
            blogObj.StartPredicate();
            Assert.AreEqual(3, blogObj.myResult.Length);
        }

經過驗證,運行良好,各個方法都按照期望的結果運行成功。通過此處對Delegate,Action,Func,Predicate的使用有個大致的瞭解,在具體的應用中根據實際情況進行調用。

總結:
1.Func,Action,Predicate都是微軟提供的定義好的委託類型,他們都位於System命名空間下,使用這幾個委託可以簡化代碼的編寫,比自定義委託使用起來更加方便;

2.Func委託具有返回值,並且可以有0到16個參數;

3.Action委託不具有返回值,可以有0到16個參數;

4.Predicate表示定義一組條件並確定指定對象是否符合這些條件的方法,他具有一個bool類型的返回值,符合由此委託表示的方法中定義的條件,則爲true,否則爲false;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章