C#4.0推出后蛉抓,類似Linq同波,Lamda表達式等許多新的程序寫法層次不窮。與之相關的Delegate厕怜,Action衩匣,F(xiàn)unc蕾总,Predicate的使用和區(qū)別也常常讓大家迷惑,此處就結合實際的應用琅捏,對其進行詳細的說明生百。
在書寫代碼時,常常會用到委托午绳,這個在winform下較常見置侍,但自定義Delegate時,我們常常發(fā)現(xiàn)Delegate必須全局可見拦焚,才能在需要的地方進行使用蜡坊,而對于私有的delegate對象,在本類中進行使用赎败,這似乎是不方便的秕衙。下邊我們來看傳統(tǒng)的Delegate的寫法。
public delegate void MyDelegate(string name);
public class MyBlogBase
{
private MyDelegate mydelegate;
}
必須保證MyDelegate放在類的外邊僵刮,才能在其他地方可見据忘,并使用,Action搞糕,F(xiàn)unc的出現(xiàn)改變了這一局面勇吊,這兩個其實說白了就是系統(tǒng)定義好的Delegate,他有很多重載的方法窍仰,便于各種應用情況下的調(diào)用汉规。他在系統(tǒng)的System命名空間下,因此全局可見驹吮。下文就說明Action针史,Action有多個重載,下文已Action<T>為例進行說明
Action<T>:封裝一個方法碟狞,該方法只有一個參數(shù)并且不返回值啄枕。其中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>:封裝一個具有一個參數(shù)并返回 TResult 參數(shù)指定的類型值的方法锯玛。其實個人感覺咐柜,F(xiàn)unc和Action的區(qū)別很明顯兼蜈,也很直接。二者都是委托拙友,但Func能返回函數(shù)執(zhí)行結果为狸,而Action返回類型是Void,這個區(qū)別很明顯遗契,在具體的項目中辐棒,也很容易確定該使用那個。下文就說明具體Func的代碼調(diào)用:
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定義漾根,大家可以選擇適合自己的編程模式,其實匿名方法鲫竞,有個優(yōu)點辐怕,就是可以直接使用當前函數(shù)出現(xiàn)的變量,代碼更簡潔从绘,但可能有些人覺得不易讀寄疏。
Predicate<T>:也是一種委托,表示定義一組條件并確定指定對象是否符合這些條件的方法.此方法常在集合的查找中被用到僵井,如:數(shù)組陕截,正則拼配的結果集中被用到。使用此方法快捷方便批什,使用代碼如下:
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;
};
}
public void StartPredicate()
{
myResult = Array.FindAll(myNum, myPredicate);
}
上例中說明了Predicate的使用农曲,F(xiàn)indAll方法中,參數(shù)2即是一個Predicate渊季,在具體的執(zhí)行中朋蔫,每一個數(shù)組的元素都會執(zhí)行指定的方法,如果滿足要求返回true却汉,并會被存放在結果集中驯妄,不符合的則被剔除,最終返回的集合合砂,即是結果判斷后想要的集合青扔,此方法應用場景感覺像迭代中的yield。當然此方法也可以書寫上邊類似Action和Func的3中方式翩伪,此處省略微猖。
為了更好的驗證運行效果,添加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);
}
經(jīng)過驗證凛剥,運行良好,各個方法都按照期望的結果運行成功轻姿。通過此處對Delegate犁珠,Action逻炊,F(xiàn)unc,Predicate的使用有個大致的了解犁享,在具體的應用中根據(jù)實際情況進行調(diào)用余素。大家對此有什么好的建議或意見,多交流炊昆。